addEventListener被忽略

问题描述 投票:1回答:1

我有一个向下拉菜单添加元素的循环。元素被添加,并且我想添加一个事件,该事件在用户单击元素之一时发生。所以我要添加一个这样的事件监听器。

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正确记录了该项目,该事件也不会触发,并且当我通过控制台手动添加侦听器时,它会起作用。我尝试使用超时功能,但没有成功。

javascript loops listener
1个回答
1
投票

当您将+=与容器的innerHTML一起使用时,仅从容器的HTML标记中就可以完全重新解析容器的内容。其他所有内容(例如不在HTML标记中的事件侦听器)都将丢失。使用insertAdjacentHTML代替:

Element接口的insertAdjacentHTML()方法将指定的文本解析为HTML或XML,并将结果节点插入到DOM树中的指定位置。它不会重新解析正在使用该元素的元素,因此不会破坏该元素内部的现有元素。这避免了额外的序列化步骤,使其比直接的innerHTML操作要快得多。

insertAdjacentHTML

就是说,您似乎只是给该元素提供了一个ID,以便您可以选择它,然后在其上附加一个侦听器。动态ID是一个非常糟糕的主意-如果使用ID作为原因,则最好使用dropdown.insertAdjacentHTML('beforeend', '<a class="dropdown-item" id="dropdown_item-' + i + '" href="#">' + cities[i] + '</a>'); 创建元素:

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:change

i

to

for (var i = 0; cities.length > i; i++) {

(或更妙的是,使用for (let i = 0; cities.length > i; i++) { 或类似的方法,而不是手动弄乱索引)

© www.soinside.com 2019 - 2024. All rights reserved.