简体   繁体   English

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

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

So I'm building a calendar program, and I want the user to be able to select a day. 所以我正在构建一个日历程序,我希望用户能够选择一天。 Using a <table> , the <td> highlights when clicked by applying className="NewStyle" to the box. 使用<table> ,通过将className="NewStyle"到框中, <td>突出显示。 I want that cell to go back to normal after clicking on another cell, but it just remains in its new style. 我希望在单击另一个单元格后该单元格恢复正常,但它仍然保持其新样式。

How do I make JS revert any non-clicked cell to normal when another cell is clicked? 当单击另一个单元格时,如何使JS将任何未单击的单元格还原为正常?

Here's a JSFiddle . 这是一个JSFiddle Thanks for any help! 谢谢你的帮助!

HTML HTML

The cells look like this: 细胞看起来像这样:

<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>

Clicking td_4 will successfully change the style. 单击td_4将成功更改样式。 But clicking td_6 will also successfully change styles, but leave td_4 in its new style instead of reverting it. 但是单击td_6也会成功更改样式,但是将td_4保留为新样式而不是还原它。

JavaScript JavaScript的

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

Just keep track of the element you clicked and unclass it. 只需跟踪您单击的元素并将其取消分类即可。 fiddle 小提琴

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

UPDATE: Another thing worth mentioning is that you can take advantage of event bubbling so that your parent container can listen to events, getting the id of the clicked element from the event object. 更新:值得一提的另一件事是你可以利用事件冒泡,这样你的父容器就可以监听事件,从事件对象中获取被点击元素的id。 updated fiddle 更新小提琴

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

and in your html get rid of all your <td onclick="change()"> and put it on parent, passing event: 并在您的HTML中删除所有<td onclick="change()">并将其放在父级,传递事件:

<table onclick="change(event)">

This is how I would achieve the effect you're looking for, but first a couple notes: 这就是我将如何实现您正在寻找的效果,但首先是几个注释:

  1. Don't use inline JavaScript 不要使用内联JavaScript
  2. If you have to repeat lots of code, it can probably be done a simpler way. 如果你必须重复大量的代码,它可能会以一种更简单的方式完成。 (read: DRY ) (读:

We are only going to use two event listeners in this script. 我们只在这个脚本中使用两个事件监听器。

The first event listener will use delegation to assign the selected class to the clicked element. 第一个事件侦听器将使用委托将所选类分配给单击的元素。 When you click on an element, the event will "bubble" up past the clicked element, all the way up through the DOM. 当您单击某个元素时,该事件将“冒泡”通过所单击的元素,一直向上通过DOM。 So we can listen to a common parent element, then check to see where the event originated. 所以我们可以听一个共同的父元素,然后检查事件的起源。

Here we want to check if the element is a <td> element, and if it does not have the class no_border . 这里我们要检查元素是否是<td>元素,以及它是否没有类no_border Then we want to use Event.stopPropagation() to stop the click event from bubbling past the common parent, which will avoid some complications with the second listener. 然后我们想使用Event.stopPropagation()来阻止click事件冒泡到公共父级,这将避免第二个侦听器出现一些并发症。 The last check we are going to do is to see if the clicked element is the selected element. 我们要做的最后一项检查是查看被点击的元素是否是所选元素。 If it is then we skip the next step and just remove the selected class. 如果是,那么我们跳过下一步并删除所选的类。

We use a common variable to store the clicked element in until the next element is clicked. 我们使用公共变量来存储单击的元素,直到单击下一个元素。 Upon the next click event we remove the selected class from the stored element's class list if there is a stored element. 在下一个单击事件时,如果存在元素,我们将从存储元素的类列表中删除所选类。 Then we assign the newly clicked element to the common variable and give it the selected class. 然后我们将新单击的元素分配给公共变量并为其提供所选的类。

The second event listener will listen to click events for the entire document. 第二个事件侦听器将侦听整个文档的单击事件。 If there is a selected element, it should hide that element. 如果存在选定元素,则应隐藏该元素。 Now the trick here is that, because we stopped the propagation of the click event from the table if the clicked element was a <td> element and didn't have the class no_border , we don't have to compare the clicked element again in order to not clash with the first event listener. 现在的诀窍是,因为如果被点击的元素是<td>元素并且没有类no_border ,我们停止了从表中传播click事件,我们不必再次比较被点击的元素为了不与第一个事件监听器发生冲突。 All we have to check is whether there is a selected element or not and if so, remove the class and reset the common variable. 我们需要检查的是是否存在选定的元素,如果是,则删除该类并重置公共变量。

 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> 

There is not much of a simple solution but try: 没有太多简单的解决方案,但尝试:

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

Or 要么

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

Use querySelector to determine the currently-checked td : 使用querySelector确定当前检查的td

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

Fiddle 1 小提琴1

You could also replace all your inline click handlers with one click handler on the table . 您还可以使用table上的一个单击处理程序替换所有内联单击处理程序。 Make sure the event's target is a td ( e.target.tagName === 'TD' ), which contains a number ( !isNaN(e.target.textContent ): 确保事件的目标是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';
  }
});

Fiddle 2 小提琴2

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

相关问题 Javascript-单击另一个子元素后获取子元素的值 - Javascript - getting the value of child element after clicking on another child element 之后将元素返回到原始CSS-jQuery / Javascript - Return element to original CSS after - jQuery / Javascript 打开选择使用javascript单击另一个元素 - Open select clicking another element with javascript 如何通过使用JavaScript单击另一个元素来更改元素的字体? - How to change the font of an element by clicking on another element with JavaScript? 通过单击元素后面的另一个元素来获取元素的innerHTML - Getting innerHTML of an element by clicking another element that comes after it 单击另一个后,还原翻转DIV - Revert flipping a DIV after clicking another one 如何在使用 JavaScript 单击它的子元素后隐藏元素 - How to hide an element after clicking it's child element using JavaScript Javascript / CSS —在单击无关元素时应用CSS样式 - Javascript/CSS — apply css style on clicking unrelated element 再次单击后如何将事件恢复为原始状态? - How to revert event to its original state after clicking on it again? 单击另一个元素后,使用 vanilla javascript 将类添加/删除到另一个元素 - Use vanilla javascript to add / remove class to a different element after clicking on another one
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM