我正在尝试创建网页,为了提高性能,我决定使用事件委派,而不是直接绑定,但我遇到了事件委派的奇怪行为或者我错过了一些东西......
这是我的HTML
的结构<div>
<section class="myClass" data-link="section 1">
<h1>Heading 1</h1>
<p>Some text....</p>
</section>
</div>
我希望整个部分都是可点击的,但在此时点击h1
p
中的section
或event.target
元素h1
或{{1}而不是p
,所以if语句中的表达式失败...
section
我已经有了直接绑定的解决方案,但是在事件委托的相同结果中实现它会很好。 这是jsFiddle
function delegate(ele) {
ele.parentNode.addEventListener("click", function (e) {
if (e.target.nodeName.toLowerCase() === "section" && e.target.classList.contains("myClass")) {
console.log("delegate " + e.target.getAttribute("data-link"));
}
}, false);
}
提前致谢!
答案 0 :(得分:3)
处理完点击后,您可以从目标开始走可视树,找到所需的信息 你可以通过类型(节点名称),按标签来寻找......为了这个例子,我只是寻找元素以获得'数据链接'属性,如果我没有在目标上找到一个,但是你有很多选择。
编辑:另一个想法是使用event.currentTarget来获取你挂钩事件的元素。
更新的小提琴将打印出来:
delegate call on h1 or p of section 1
单击h1或p1
它会打印出来:
delegate section 1
点击整个部分。
function delegate(ele) {
ele.parentNode.addEventListener("click", delegateHandler, false);
}
function delegateHandler (e) {
var target = e.target;
var attribute = target.getAttribute("data-link");
// if target has no attribute
// seek it on its parent
if (!attribute) {
attribute = target.parentNode.getAttribute("data-link");
}
if ( target.classList.contains("myClass") ) {
console.log("delegate " + attribute);
}
else console.log('delegate call on h1 or p of ' + attribute);
}
Rq:我没理解为什么你把事件挂钩在元素的父元素上,可能更简单,不去做。 : - )
答案 1 :(得分:2)
我找到了 CSS pointer-events
的解决方案.myClass * {
pointer-events: none;
}
或 JavaScript
(function () {
"use strict";
var ele = document.querySelector(".myClass").parentNode;
delegate(ele);
function delegate(ele) {
ele.addEventListener("click", function (e) {
var target = e.target;
while (!(target.nodeName.toLowerCase() === "section" && target.classList.contains("myClass"))) {
target = target.parentNode;
if (target === ele) {
break;
}
}
if (target.nodeName.toLowerCase() === "section" && target.classList.contains("myClass")) {
console.log("delegate " + target.getAttribute("data-link"));
}
});
}
}());
答案 2 :(得分:1)
将事件监听器添加到ele
而不是ele.parentNode
,并使用this
代替e.target
。
function delegate(ele) {
ele.addEventListener("click", function (e) {
if (this.nodeName.toLowerCase() === "section" && this.classList.contains("myClass")) {
console.log("delegate " + this.getAttribute("data-link"));
}
}, false);
}
请注意e.target
是调度事件的元素。但在您的情况下,您不希望这样,您需要具有事件处理程序的元素,因此请使用this
(或ele
)。