事件委派,如何定位div内的特定跨度

时间:2017-01-04 18:29:31

标签: javascript event-delegation

给出了一堆像这样的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)
  }
})

3 个答案:

答案 0 :(得分:4)

您的代码不合适event delegation

您应该检查是否在div内点击class=fruit。然后,您可以从text后代中提取span

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);
    }
});

答案 1 :(得分:1)

使用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>

答案 2 :(得分:-2)

稍微改编一下场景:

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>