事件委托,如何针对 div 中的特定跨度
Event Delegation, how to target a specific span inside a div
给定一堆这样的 div:
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
我希望能够使用事件委托在我单击这些 div 时获取范围的值(因此只是文本)。
有了这个我得到了一切,文本和符号,但我似乎无法只得到跨度内的文本:
const fruitButtons = document.querySelectorAll(".fruit span");
const grid = document.querySelector(".itemGrid");
grid.addEventListener("click", function(e) {
if (e.target.nodeName == "DIV") {
console.log(e.target.textContent)
}
})
使用getElementsByTagName()找到目标下的span个元素。
编辑:
正如所指出的,可以解释 隐式 要求,即用户应该能够单击 span 元素并具有记录该元素的内容。通过添加 while 循环来向上搜索祖先链来添加对此的支持:
//search ancestors for div in case user clicks on span element
while (target.nodeName !== "DIV" && e.target.parentNode !== null) {
target = e.target.parentNode;
}
const fruitButtons = document.querySelectorAll(".fruit span");
const grid = document.querySelector(".itemGrid");
grid.addEventListener("click", function(e) {
var target = e.target;
//search ancestors for div in case user clicks on span element
while (target.nodeName !== "DIV" && e.target.parentNode !== null) {
target = e.target.parentNode;
}
if (target.nodeName == "DIV") {
var spans = target.getElementsByTagName('span');
if (spans.length) {
console.log(spans[0].textContent);
}
}
})
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
稍微修改场景:
const fruitButtons = document.querySelectorAll(".fruit > span");
const gridItems = document.querySelectorAll(".fruit");
// Loop through the div.fruit elements:
gridItems.forEach(function(div){
// Wire each div.fruit to a click handler:
div.addEventListener("click", function(e){
// When clicked, look for the first span within the div and get its text
console.log(div.querySelector("span").textContent);
});
});
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
您的代码不正确event delegation
您应该检查是否在 div
中单击了 class=fruit
。然后你可以从它的 span
后代中提取 text
。
grid.addEventListener("click", function(e) {
let node = e.target;
let div = null;
// first let's check if we clicked inside div with class fruit by going up the DOM tree
while(node !== this){
if(node.hasClass("fruit")){
div = node;
break;
}
node = node.parentNode;
}
// if we clicked inside, log the value of span
if(div !== null){
console.log(div.querySelector("span").textContent);
}
});
给定一堆这样的 div:
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
我希望能够使用事件委托在我单击这些 div 时获取范围的值(因此只是文本)。
有了这个我得到了一切,文本和符号,但我似乎无法只得到跨度内的文本:
const fruitButtons = document.querySelectorAll(".fruit span");
const grid = document.querySelector(".itemGrid");
grid.addEventListener("click", function(e) {
if (e.target.nodeName == "DIV") {
console.log(e.target.textContent)
}
})
使用getElementsByTagName()找到目标下的span个元素。
编辑:
正如所指出的,可以解释 隐式 要求,即用户应该能够单击 span 元素并具有记录该元素的内容。通过添加 while 循环来向上搜索祖先链来添加对此的支持:
//search ancestors for div in case user clicks on span element
while (target.nodeName !== "DIV" && e.target.parentNode !== null) {
target = e.target.parentNode;
}
const fruitButtons = document.querySelectorAll(".fruit span");
const grid = document.querySelector(".itemGrid");
grid.addEventListener("click", function(e) {
var target = e.target;
//search ancestors for div in case user clicks on span element
while (target.nodeName !== "DIV" && e.target.parentNode !== null) {
target = e.target.parentNode;
}
if (target.nodeName == "DIV") {
var spans = target.getElementsByTagName('span');
if (spans.length) {
console.log(spans[0].textContent);
}
}
})
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
稍微修改场景:
const fruitButtons = document.querySelectorAll(".fruit > span");
const gridItems = document.querySelectorAll(".fruit");
// Loop through the div.fruit elements:
gridItems.forEach(function(div){
// Wire each div.fruit to a click handler:
div.addEventListener("click", function(e){
// When clicked, look for the first span within the div and get its text
console.log(div.querySelector("span").textContent);
});
});
<div class="itemGrid">
<div id="itemOne" class="fruit">
<span> Banana </span>
</div>
<div id="itemTwo" class="fruit">
<span> Apple </span>
</div>
</div>
您的代码不正确event delegation
您应该检查是否在 div
中单击了 class=fruit
。然后你可以从它的 span
后代中提取 text
。
grid.addEventListener("click", function(e) {
let node = e.target;
let div = null;
// first let's check if we clicked inside div with class fruit by going up the DOM tree
while(node !== this){
if(node.hasClass("fruit")){
div = node;
break;
}
node = node.parentNode;
}
// if we clicked inside, log the value of span
if(div !== null){
console.log(div.querySelector("span").textContent);
}
});