[英]JavaScript Event Delegation - Behavior
我試圖創建網頁並提高性能,因此決定使用事件委托而不是直接綁定,但是遇到事件委托的奇怪行為,或者我錯過了某些事情...
這是我的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
或p
,而不是section
,所以表達的if語句失敗...
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);
}
我已經有了直接綁定的解決方案,但是與事件委派在同一結果中實現效果會更好。 這是jsFiddle
function direct(ele) {
[].forEach.call(ele, function (value, index, array) {
value.addEventListener("click", function(e) {
console.log("direct " + value.getAttribute("data-link"));
}, false);
});
}
提前致謝!
處理完點擊之后,您可以從目標開始瀏覽視覺樹,以找到所需的信息。
為了示例,您可能按類型(節點名稱),按標記搜索... ...如果我在目標上找不到一個,則我只是在元素上搜索以獲得“數據鏈接”屬性,但是您在這里有很多選擇。
編輯:另一個想法是使用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:我不明白為什么將事件掛在元素的父元素上,不這樣做可能更簡單。 :-)
我找到了使用CSS 指針事件的解決方案
.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"));
}
});
}
}());
將事件監聽器添加到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
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.