繁体   English   中英

JavaScript - 单击另一个元素后将元素恢复为原始样式

[英]JavaScript - Revert element to original style after clicking another element

所以我正在构建一个日历程序,我希望用户能够选择一天。 使用<table> ,通过将className="NewStyle"到框中, <td>突出显示。 我希望在单击另一个单元格后该单元格恢复正常,但它仍然保持其新样式。

当单击另一个单元格时,如何使JS将任何未单击的单元格还原为正常?

这是一个JSFiddle 谢谢你的帮助!

HTML

细胞看起来像这样:

<td id="td_4" onclick="change(4)">4</td>
<td id="td_5" onclick="change(5)">5</td>
<td id="td_6" onclick="change(6)">6</td>

单击td_4将成功更改样式。 但是单击td_6也会成功更改样式,但是将td_4保留为新样式而不是还原它。

JavaScript的

function change(x) {
    document.getElementById("td_" + x).className = "selected";
}

只需跟踪您单击的元素并将其取消分类即可。 小提琴

var previousEl
function change(x) {
  if (previousEl) previousEl.className = ""
  previousEl = document.getElementById("td_" + x)
  previousEl.className = "selected"
}

更新:值得一提的另一件事是你可以利用事件冒泡,这样你的父容器就可以监听事件,从事件对象中获取被点击元素的id。 更新小提琴

var previousEl
function change(event) {
  if (previousEl) previousEl.className = "";
  previousEl = document.getElementById(event.target.id)
  previousEl.className = "selected";
}

并在您的HTML中删除所有<td onclick="change()">并将其放在父级,传递事件:

<table onclick="change(event)">

这就是我将如何实现您正在寻找的效果,但首先是几个注释:

  1. 不要使用内联JavaScript
  2. 如果你必须重复大量的代码,它可能会以一种更简单的方式完成。 (读:

我们只在这个脚本中使用两个事件监听器。

第一个事件侦听器将使用委托将所选类分配给单击的元素。 当您单击某个元素时,该事件将“冒泡”通过所单击的元素,一直向上通过DOM。 所以我们可以听一个共同的父元素,然后检查事件的起源。

这里我们要检查元素是否是<td>元素,以及它是否没有类no_border 然后我们想使用Event.stopPropagation()来阻止click事件冒泡到公共父级,这将避免第二个侦听器出现一些并发症。 我们要做的最后一项检查是查看被点击的元素是否是所选元素。 如果是,那么我们跳过下一步并删除所选的类。

我们使用公共变量来存储单击的元素,直到单击下一个元素。 在下一个单击事件时,如果存在元素,我们将从存储元素的类列表中删除所选类。 然后我们将新单击的元素分配给公共变量并为其提供所选的类。

第二个事件侦听器将侦听整个文档的单击事件。 如果存在选定元素,则应隐藏该元素。 现在的诀窍是,因为如果被点击的元素是<td>元素并且没有类no_border ,我们停止了从表中传播click事件,我们不必再次比较被点击的元素为了不与第一个事件监听器发生冲突。 我们需要检查的是是否存在选定的元素,如果是,则删除该类并重置公共变量。

 var selected; document.getElementById( 'calendar' ).onclick = function( e ) { var c = e.target; if( c.tagName === 'TD' && c.className.indexOf( 'no_border' ) === -1 ) { e.stopPropagation(); if( c.className.indexOf( 'selected' ) === -1 ) { if( selected ) selected.className = selected.className.replace( /\\s?selected/, '' ); selected = c; selected.className += ' selected'; } else c.className = c.className.replace( /\\s?selected/, '' ); } } document.body.onclick = function( e ) { if( selected ) { selected.className = selected.className.replace( /\\s?selected/, ''); selected = false; } } 
 td { padding:4px; border:solid #ccc 1px; text-align: center; } td::after { /* I added this to keep a consistent width */ content: ""; display: block; width: 2em; } .no_border { border: 1px solid transparent; } .selected { border: solid #69F 1px; } 
 <table id="calendar"> <thead> <tr><td class="no_border">Sun</td><td class="no_border">Mon</td><td class="no_border">Tue</td><td class="no_border">Wed</td><td class="no_border">Thu</td><td class="no_border">Fri</td><td class="no_border">Sat</td></tr> </thead> <tbody> <tr><td class="no_border" colspan="6"></td><td>1</td></tr> <tr><td>2</td> <td>3</td> <td>4</td> <td>5</td> <td>6</td> <td>7</td> <td>8</td></tr> <tr><td>9</td> <td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td></tr> <tr><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td></tr> <tr><td>23</td><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td></tr> <tr><td>30</td><td>31</td></tr> </tbody> </table> 

没有太多简单的解决方案,但尝试:

function change(x) {
    document.getElementsByTagName('td').forEach(function (el) {
        if (el.className === 'selected') {
            el.className = '';
        }
    });
    document.getElementById("td_" + x).className = "selected";
}

要么

function change(x) {
    document.getElementsByClassName('selected').forEach(function (el) {
        el.className = '';
    });
    document.getElementById("td_" + x).className = "selected";
}

使用querySelector确定当前检查的td

function change(x) {
  var sel= document.querySelector('td.selected');
  if(sel) sel.className= '';
  document.getElementById("td_" + x).className = "selected";
}

小提琴1

您还可以使用table上的一个单击处理程序替换所有内联单击处理程序。 确保事件的目标是tde.target.tagName === 'TD' ),其中包含一个数字( !isNaN(e.target.textContent ):

document.querySelector('table').addEventListener('click', function(e) {
  if(e.target.tagName === 'TD' && !isNaN(e.target.textContent)) {
    var sel= document.querySelector('td.selected');
    if(sel) sel.className= '';
    e.target.className= 'selected';
  }
});

小提琴2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM