将 EventListener 定义为 javascript 中的 ul 列表项时出现问题

Problems defining EventListener to ul List items in javascript

我正在将 javascript 中的列表项添加到 ul id 'showingDeck'。我想初始化 li class 'card',并初始化 addEventListener,然后在单击时更改列表项的 class(CSS 格式)。

for (var i = 0; i < shuffledCards.length; i++) {
    var ul = document.getElementById("showingDeck");
    var li = document.createElement("li");
    li.innerHTML = shuffledCards[i];
    li.className = 'card';
    document.getElementById("showingDeck").appendChild(li);
    document.getElementById("showingDeck").addEventListener("click", processClicks(li));
};

processClicks 在没有点击的情况下被触发 16 次,并且没有点击被注册。

Event Delegation

如果您动态添加 <li>,那么事件永远不会粘住它们。标签必须在页面加载时存在才能被注册。所以你需要使用 Event Delegation.

  • 首先获取满足两个条件的标签:

    1. 页面加载时必须存在。
    2. 必须是您想要点击、悬停等的标签的祖先(父级或 parent 的父级,等等...)
  • 接下来将所述标签注册到事件(顺便说一句,祖先标签甚至可以是 documentwindow,但建议您将它们用于关键事件或非DOM 事件)

      ancestorTag.addEventListener('event', callback);
    
  • 只要在祖先标记或其后代(子代或子代等)上触发注册事件,就会调用回调函数。

  • 正是在这段时间里,祖先标签现在可以被引用为event.currentTarget and more importantly, the tagged that was actually clicked, hovered over, erc... is now referenced as event.target

  • 标签是否具有 #id.className、学生 ID 或其他任何内容都无关紧要,因为 event.target 将是特定的标签(在那方面:this).


优点

  • 无限数量的标签只需要一个事件监听器

  • 动态添加标签的问题已解决

  • 没有 #ids, .classNames, 出生证明, erc.需要识别点击的标签。

缺点

  • None 这就是为什么我们不应该使用 on-event` attributes 或向一百个标签添加事件监听器的原因。

演示

var list = document.getElementById('list');

list.addEventListener('click', callback);

function callback(event) {
  var clicked = event.target;
  var listener = event.currentTarget;
  if (clicked !== listener) {
    clicked.classList.toggle('active');
  } else {
    return false;
  }
  return false
}
.active {
  color: gold;
  background: #000;
}
<ul id='list'>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
</ul>