Событие не пузырится, как я думаю, это должно
У меня есть динамически генерируемая страница предметов в инвентаре. Я пытаюсь создать событие onclick, чтобы, если пользователь нажимает на отображаемую информацию об элементе или изображение, выполняется список событий. Я могу заставить его работать, добавив onclick="doSomething(this.id) в HTML, но не могу заставить его работать с использованием методов ни в одном из всплывающих событий, а также в учебниках по делегированию событий, которые я видел. Изображение элемента, и данные представлены в отдельных таблицах HTML, по одной для каждого элемента. Каждому присваивается уникальный идентификатор, и все они содержатся в одном элементе контейнера div. addEventListener назначается элементу div вместо наличия прослушивателя для каждой таблицы. Похоже, что происходит, это событие события click для элемента img, элемента td. tr или таблицы, и, если я буду очень осторожен, поместим курсор перед щелчком на элементе таблицы. что я делаю. Я должен быть в состоянии заставить его срабатывать на каждом последующем элементе, но что-то останавливает распространение.
Мне нужно для получения уникального идентификатора (таблицы) при нажатии на эту таблицу или любой элемент-потомок.
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) должен выполнить console.log(clickedItem) для каждого объекта-потомка вплоть до, но не включая currentTarget. Это не так, даже если я уберу проверку if(). Я хотел бы получить некоторые пояснения по этому вопросу, но, что более важно, я бы хотел переработать оператор if, чтобы он был истинным только для кликов на прямых потомках currentTarget.
1 ответ
Я обнаружил, что если я добавлю одного и того же слушателя к каждому элементу в сегменте дерева DOM, один щелчок мыши будет вызывать событие щелчка для каждого элемента, начиная с элемента, по которому щелкают, и перемещаясь вверх по каждому последующему элементу (всплывание). Затем я могу проверить каждый узел на предмет "name" className и, когда он найден, прочитать его идентификатор. Это дает желаемый результат, но означает, что сотням элементов назначен один и тот же слушатель. Вероятно, это всего лишь несколько сотен указателей, но это не кажется мне очень эффективным
Однако, если я добавляю слушателя только к верхнему элементу, событие click запускает слушателя только один раз, независимо от того, какой элемент фактически получил щелчок (например, img, но не td, в котором он находится, или tr, в котором находится td и т. Д.). Я вижу много причин, это хорошо в нормальных условиях, но это не то, что мне нужно.
Размышляя об этом, я придумал следующее решение. Я добавляю слушателя к верхнему элементу. Затем обработчик проверяет, имеет ли e.target имя_класса "item", если нет, он перебирает каждого последующего родителя до тех пор, пока не находит узел с className "item", а затем считывает идентификатор этого узла (который является элементом инвентаризации). номер, который я ищу).
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>