2017-05-05 64 views
1

面对我无法理解如何使用元素语句进行管理的事情,如使用事件侦听器切换类。下面的代码显示了带有click事件的按钮,它添加了类,如果其他人有这个类,它将它删除。但是每次最后一个按钮都不会对该事件做出反应。任何人都可以解释为什么以及如何处理它?来自queryselector和eventlistener问题的数组问题

let buttons = document.querySelectorAll('button'); 
 
Array.from(buttons).forEach(function(el, i){ 
 
\t el.addEventListener('click', function(){ 
 
\t \t 
 
\t \t for(let val of buttons) { 
 
\t \t \t console.log(val) 
 
\t \t \t if(val.classList.contains('red')){ 
 
\t \t  \t \t val.classList.remove('red'); 
 
\t \t \t } else { 
 
\t \t  \t \t el.classList.add('red'); 
 
\t \t  } 
 
\t \t } \t \t 
 
\t }) 
 
})
.red { 
 
\t color: red; 
 
}
<button>button 1</button> 
 
<button>button 2</button> 
 
<button>button 3</button>

,并有更好的方式来处理这个班通过纯JS切换?

回答

1

你做了一些错误,在你的if-else语句代码:

在这里,我纠正:

let buttons = document.querySelectorAll('button'); 
 
Array.from(buttons).forEach(function(el, i){ 
 
\t el.addEventListener('click', function(){ 
 
\t \t 
 
\t \t for(let val of buttons) { 
 
\t \t \t if(val.classList.contains('red')){ 
 
\t \t  \t \t val.classList.remove('red'); 
 
\t \t \t } 
 
       el.classList.add('red'); 
 
\t \t   console.log(val) 
 
\t \t } \t \t 
 
\t }) 
 
})
.red { 
 
\t color: red; 
 
}
<button>button 1</button> 
 
<button>button 2</button> 
 
<button>button 3</button>

希望,它会为你工作。谢谢

+0

什么是错的'如果 - else'?你在'if-else'中改变了什么,除了'console.log'是什么? – caramba

+0

我已经删除了代码中的else条件。 –

+0

是的,它的工作原理......但其他条件有什么问题...为什么总是最后一个元素不会在这种情况下做出反应? – NeedHate

2

因此,你不想将红色类添加到你点击的类中并从其他所有类中删除它?

const buttons = document.querySelectorAll('button'); 
 

 
Array.from(buttons).forEach(function(x){ 
 
\t x.addEventListener('click', function(b){ \t \t 
 
\t \t unsetRed(); 
 
\t \t b.srcElement.classList.add('red'); 
 
\t }) 
 
}) 
 

 
function unsetRed(){ 
 
\t [].forEach.call(document.querySelectorAll('button.red'), function(x) { 
 
\t \t x.classList.remove('red'); 
 
\t }); 
 
}
.red { 
 
    color:red; 
 
}
<button>Button</button> 
 
<button>Button</button> 
 
<button>Button</button>

+0

我认为其他方式也是如此。 ) – NeedHate

+0

@Werner这是更好的解决上述问题的方法。也清楚!奖励! –

1

所以首先是想说明,你有一点点缩短了代码。它不完全是你想要的(将在下一个片段中显示)。但它所做的几乎是你想要的。点击它将红色班级切换。缺少的部分是,它不会切换所有其他按钮。

let buttons = document.querySelectorAll('button'); 
 
buttons.forEach(function(element){ 
 
\t element.addEventListener('click', function(){ 
 
    \t \t if(element.classList.contains('red')){ 
 
\t \t  \t \t element.classList.remove('red'); 
 
\t \t \t } else { 
 
\t \t  \t \t element.classList.add('red'); 
 
\t \t } 
 
\t }); 
 
});
.red { 
 
\t color: red; 
 
}
<button>button 1</button> 
 
<button>button 2</button> 
 
<button>button 3</button>

所以一些解释将在代码中找到。但首先。切勿切换像red这样的课程,但切换类似active的课程。为什么?因为如果你的客户想要把它改成绿色,你只需要改变你的CSS而不是JS。如果您将代码与上面的代码进行比较,则没有太大区别。除了在添加正在移除所有活动类的类活动之前,我们会做更多的工作。

这只是给你一个想法如何handlefire事件。你可以做更多的事情。就像传递论据,元素或你需要的东西一样。为了获得和正确的东西反应...

let buttons = document.querySelectorAll('button'); 
 
buttons.forEach(function(element){ 
 
    element.addEventListener('click', function(){ 
 
     if(element.classList.contains('active')){ 
 
      element.classList.remove('active'); 
 
     } else { 
 
      // this is like: "Fire event on the document" 
 
      document.dispatchEvent(new CustomEvent('toggle-all-my-buttons', {})); 
 
      element.classList.add('active'); 
 
     } 
 
    }); 
 
}); 
 

 
// here we listen on the document and can react if it gets fired no matter from where 
 
document.addEventListener('toggle-all-my-buttons', function(){ 
 
    console.log('toggle all my buttons'); 
 
    buttons.forEach(function(element){ 
 
     element.classList.remove('active'); 
 
    }); 
 
});
.active { 
 
    color: red; 
 
}
<button>button 1</button> 
 
<button>button 2</button> 
 
<button>button 3</button>

Read more about CustomEvents here

+0

感谢您的解释。只是用来显示我正在做的事情。但是不是创建一个自定义事件更简单吗? – NeedHate

+1

@NeedHate很好,当然可以。但是,如果你习惯于使用事件,那也不是什么大不了的事情。这也是非常明显的,它是超级可维护的。就像如果您的应用程序变得更大,并且某件事情改变了您的按钮的状态那么简单。只听这个事件,发起事件,并瞧瞧。我想最重要的是为所有的自定义事件找出好名字。因为如果你在文件上解雇他们,你只能使用他们一次 – caramba

+1

我已经接受@Hassan Imam的答案,但是也考虑过你的答案。这非常有用。谢谢! – NeedHate