无法使用classList API选择所有元素

时间:2014-09-02 12:16:05

标签: javascript event-delegation

在将jQuery代码转换为HTML5 javascript时,我在选择所有LI标记时遇到问题 码。我已将click事件应用于父UL,并且click事件正应用于正确的单击目标LI。课程"选择"也正在应用。问题是我需要在"选择"之前从LI标签中清除所有类。 class被应用,因为我只想将它应用于当前事件目标。在jQuery中,只需要从LI中删除类,但是我遇到了针对所有LI标记并在javascript中删除类的问题。我怀疑问题是我如何迭代从QuerySelectorAll返回的节点列表。我还试过了其他的东西,document.GetElementsByTagName,并迭代这些。

我得到一个"未捕获的TypeError:无法读取属性'包含'未定义"在myFunc函数上。

如果有人可以指出我的错误,我会很高兴。

<div id='button'></div>
 <ul id='swatches'>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
 </ul>

jQuery代码

$('li').on('click', function(){
 $('li').removeClass('selected');
 $(this).toggleClass('selected');
});

使用classList API

var swatch = document.getElementById('swatches'),
$li = document.querySelectorAll('#swatches li');

swatch.addEventListener('click', myFunc, false);

function myFunc(e){
  var target = e.target;

  for(var i=0; i<$li.length; i++){
   if($li.classList.contains('selected')){
   $li.classList.remove('selected');
  }
} 
if(target.nodeName.toLowerCase() === 'li'){
 e.target.classList.toggle('selected');
}

}

1 个答案:

答案 0 :(得分:1)

  

我怀疑问题是我如何迭代从QuerySelectorAll返回的节点列表。

是。你忘记了指数。它应该是

for (var i=0; i<$li.length; i++)
    if ($li[i].classList.contains('selected'))
//         ^^^
        $li[i].classList.remove('selected');
//         ^^^

然而,有两点:

  • 除非您明确需要这些信息,否则在调用contains()之前无需测试remove()。试图删除一个不存在的类只会做什么。
  • 您可能不需要在每次点击时迭代整个$li集合。由于一次只有一个<li> .selected类,您可能只是存储对当前所选元素的引用,或者使用

    var cur = swatch.querySelector("li.selected");
    if (cur) cur.classList.remove('selected');
    

    (也可以使用id)。