将 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.
首先获取满足两个条件的标签:
- 页面加载时必须存在。
- 必须是您想要点击、悬停等的标签的祖先(父级或 parent 的父级,等等...)
接下来将所述标签注册到事件(顺便说一句,祖先标签甚至可以是 document
或 window
,但建议您将它们用于关键事件或非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>
我正在将 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.
首先获取满足两个条件的标签:
- 页面加载时必须存在。
- 必须是您想要点击、悬停等的标签的祖先(父级或 parent 的父级,等等...)
接下来将所述标签注册到事件(顺便说一句,祖先标签甚至可以是
document
或window
,但建议您将它们用于关键事件或非DOM 事件)ancestorTag.addEventListener('event', callback);
只要在祖先标记或其后代(子代或子代等)上触发注册事件,就会调用回调函数。
正是在这段时间里,祖先标签现在可以被引用为
event.currentTarget
and more importantly, the tagged that was actually clicked, hovered over, erc... is now referenced asevent.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>