我有一个库存中动态生成的项目页面。我试图创建一个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的直接后代单击时才为真。
答案 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>