所以我正在构建一个日历程序,我希望用户能够选择一天。使用<table>
时,<td>
会在className="NewStyle"
应用<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>
时突出显示。我希望在单击另一个单元格后该单元格恢复正常,但它仍然保持其新样式。
当点击另一个单元格时,如何让JS将任何未单击的单元格恢复为正常?
这是一个JSFiddle。谢谢你的帮助!
HTML
细胞看起来像这样:
td_4
单击td_6
将成功更改样式。但点击td_4
也会成功更改样式,但请将function change(x) {
document.getElementById("td_" + x).className = "selected";
}
保留为新样式,而不是将其恢复。
的JavaScript
$myCarousel.carousel('pause');
答案 0 :(得分:4)
只需跟踪您点击的元素并将其取消分类即可。 fiddle
var previousEl
function change(x) {
if (previousEl) previousEl.className = ""
previousEl = document.getElementById("td_" + x)
previousEl.className = "selected"
}
更新:值得一提的另一件事是你可以利用事件冒泡,这样你的父容器就可以监听事件,从事件对象中获取被点击元素的id。 updated fiddle
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 :(得分:3)
这就是我将如何实现您正在寻找的效果,但首先要注意几个:
我们只会在此脚本中使用两个事件侦听器。
第一个事件侦听器将使用委托将所选类分配给单击的元素。当您单击某个元素时,该事件将“冒泡”通过所单击的元素,一直向上通过DOM。所以我们可以听一个共同的父元素,然后检查事件的起源。
这里我们要检查元素是否是<td>
元素,以及它是否没有类no_border
。然后我们想要使用Event.stopPropagation()
来阻止点击事件冒泡过公共父级,这将避免第二个侦听器出现一些复杂情况。我们要做的最后一项检查是查看被点击的元素是否是所选元素。如果是,那么我们跳过下一步,只删除选定的类。
我们使用公共变量来存储单击的元素,直到单击下一个元素。在下一个单击事件时,如果存在元素,我们将从存储元素的类列表中删除所选类。然后我们将新点击的元素分配给公共变量并为其提供所选的类。
第二个事件侦听器将侦听整个文档的单击事件。如果存在选定元素,则应隐藏该元素。现在的诀窍是,因为如果点击的元素是<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>
答案 2 :(得分:1)
没有太多简单的解决方案,但请尝试:
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";
}
答案 3 :(得分:1)
使用querySelector确定当前已检查的td
:
function change(x) {
var sel= document.querySelector('td.selected');
if(sel) sel.className= '';
document.getElementById("td_" + x).className = "selected";
}
您还可以使用table
上的一个点击处理程序替换所有内联点击处理程序。确保事件的目标是td
(e.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';
}
});