事件不会像我认为的那样冒泡

时间:2018-08-12 20:09:44

标签: javascript events delegation

我有一个库存中动态生成的项目页面。我试图创建一个onclick事件,以便如果用户单击显示的项目信息或图像,则事件列表器将执行。我可以通过在HTML中添加onclick =“ doSomething(this.id)来使其工作,但是不能使用任何事件冒泡和事件委托教程中的方法来使其工作。 项目图像和数据显示在单独的HTML表中,每个表一个。每个容器都有唯一的ID,并且都包含在单个容器div元素中。将addEventListener分配给div,而不是为每个表都有一个侦听器。 似乎正在发生的是img元素(即td元素)的click事件触发器。 tr或表格,如果我非常小心,请在单击表格元素之前放置光标。不管我做什么,该事件似乎都没有发生。我应该能够在每个连续的元素上触发它,但是某些东西正在阻止传播。
当该表格或任何后代元素被点击时,我需要检索(表格的)唯一ID。

var theParent = document.querySelector('#container');
theParent.addEventListener("click", doSomething);
}

function doSomething(e) {
  console.log(e.target.id) + "   \r\n";
  if (e.target !== e.currentTarget) {
    var clickedItem = e.target.nodeName;
    console.log(clickedItem);
  }
}
<div id="container">
  <table class="items" id="1234">
    <tr>
      <td>
        <img src="path/to/item.jpg">
      </td>
      <td>
        this is item 1234
      </td>
    </tr>
  </table>
  ...
</div>

<div id="container">
   <div  class="items" id="1234">
     <table>
       <tr>
         <td>
          <img src="path/to/item.jpg">
         </td>
         <td>
           this is item 1234
         </td>
       </tr>
     </table>
   </div>
    ...
</div>   

我认为if(e.target!== e.currentTarget)应该为直到但不包括currentTarget的每个后代对象执行console.log(clickedItem)。即使我删除了if()筛选,也不会。我想对此进行一些说明,但更重要的是,我希望将if语句仅在对currentTarget的直接后代单击时才为真。

1 个答案:

答案 0 :(得分:0)

我发现,如果将相同的侦听器添加到DOM树段中的每个元素,则单击一次鼠标将为每个元素触发一个click事件,从单击的元素开始,沿每个连续的元素向上移动(冒泡)。然后,我可以测试每个节点的className“ item”,并在找到时读取其ID。这产生了我想要的结果,但是意味着数百个元素被分配了相同的侦听器。它可能只是数百个指针,但并没有让我感到非常有效

但是,如果我将侦听器仅添加到顶部元素,那么无论哪个元素实际接收到点击,click事件都只会触发一次侦听器(例如img但它所在的td或td所在的tr等) )。我看到很多原因,在正常情况下这是件好事,但没有满足我的需要。

考虑一下,我想出了以下解决方案。我将侦听器添加到顶部元素。然后,处理程序测试e.target是否具有className为“ item”,如果不是,它将遍历每个后续父级,直到找到具有className为“ item”的节点,然后读取该节点的ID(即库存项目)我要寻找的号码)。

function doSomething(e) {
   if(e.target !== e.currentTarget){
        var el =  e.target;
        do {
          el = el.parentNode;
        } while (el.className !="item");

        var clickedItem = el.id;
        console.log("Clicked item id: " + clickedItem);
   }
}

topofTree= document.querySelector('#container') ;
topofTree.addEventListener("click",doSomething)  ;
<div id="container">
  <table class="item" id="0064">
    <tr>
      <td><img src="/spiritmasks/images/MSK_spirit_mask_8.jpg" ></td>
      <td>
        <table>
          <tr><td>Item ID:</td><td>0064</td></tr>
          <tr><td>Display Name:</td><td>Spirit Mask #8</td></tr>
          <tr><td>Description:</td><td></td></tr>
          <tr><td>Type:</td><td>SPIRIT MASK</td></tr>
          <tr><td>Location:</td><td>GALLERY</td></tr>
          <tr><td>In Slide Show:</td><td>NO</td></tr>
          <tr><td>Size:</td><td></td></tr>
          <tr><td>Price:</td><td></td></tr>
          <tr><td>Comments:</td><td></td></tr>
        </table>
      </td>
    </tr>
  </table>
</div>