javascript - addEventListener 被忽略
问题描述
我有一个将元素添加到下拉列表的循环。添加了元素,我想添加一个在用户单击其中一个元素时发生的事件。所以我正在添加一个这样的事件监听器。
for (var i = 0; cities.length > i; i++) {
if (cities[i].toLowerCase().indexOf(value.toLowerCase()) !== -1 && citiesList <= 10) {
citiesList ++;
dropdown.classList.add('show');
dropdown.innerHTML += '<a class="dropdown-item" id="dropdown_item-' + i + '" href="#">' + cities[i] + '</a>';
var item = document.getElementById('dropdown_item-' + i);
item.addEventListener("click", function(){ console.log("test") });
console.log(item);
}
}
但是,当我单击元素时,即使 console.log 正确记录了该项目,事件也不会触发,并且当我通过控制台手动添加侦听器时它可以工作。我尝试使用超时功能,但没有占上风。
解决方案
当您+=
使用innerHTML
容器时,容器的内容会完全从它们的 HTML 标记中重新解析。其他任何内容(例如不在 HTML 标记中的事件侦听器)都将丢失。改为使用insertAdjacentHTML
:
Element 接口的 insertAdjacentHTML() 方法将指定的文本解析为 HTML 或 XML,并将生成的节点插入到 DOM 树中的指定位置。它不会重新解析正在使用的元素,因此不会破坏该元素内的现有元素。这避免了额外的序列化步骤,使其比直接的 innerHTML 操作快得多。
dropdown.insertAdjacentHTML('beforeend', '<a class="dropdown-item" id="dropdown_item-' + i + '" href="#">' + cities[i] + '</a>');
也就是说,看起来您可能只是为元素提供了一个 ID,以便您可以选择它并随后将侦听器附加到它。动态 ID 是一个非常糟糕的主意 - 如果是 ID 的原因,最好使用以下方法创建元素createElement
:
const a = document.createElement('a');
a.className = "dropdown-item";
a.textContent = cities[i];
a.addEventListener("click", function() {
console.log("test")
});
dropdown.appendChild(a);
请记住,给定您当前的代码,这i
将等于cities.length
循环结束后。如果您i
在侦听器回调中引用,如果您希望它引用i
用于该特定迭代的,您需要一个块范围的i
代替:更改
for (var i = 0; cities.length > i; i++) {
至
for (let i = 0; cities.length > i; i++) {
(或者,甚至更好,使用Array.prototype.forEach
或类似的东西,而不是手动弄乱索引)
推荐阅读
- c++ - 双向链表上的二分查找
- c - 带有条目的 GtkComboBox 导致 `gtk_entry_set_text: assertion 'text != NULL' failed`
- java - 如何动态排序 spring jpa 中嵌套 Map 的值?
- firebase - 如何在颤动中找到附近的人并将两者同时添加到对话中
- service - 服务激活期间使用内部模式安装 APIM 失败
- c# - 使用'Distinct()'时仍然得到重复的字符串
- java - 如何从 Java Lambda 调用 SigV4 授权的 API 网关
- python - 如何在python中将整数转换为列表?
- node.js - 在带有参数化查询的 nodejs 中返回 Postgres 结果
- c# - 有没有办法将相同类型的参数分组以使代码整洁?