gpt4 book ai didi

javascript - 将 click 事件绑定(bind)到在嵌套 for 循环中创建的元素

转载 作者:行者123 更新时间:2023-12-03 11:12:20 25 4
gpt4 key购买 nike

今天我已经阅读了很多关于闭包的内容,并且浏览了很多类似的问题。我无法找到一个与我遇到的完全相同的问题以及如何解决它的解决方案。大多数答案似乎都与 jQuery 相关,但也有一些关于闭包如何工作的精彩答案。我知道这就是我的问题所在。我尝试了许多不同的关闭示例,但没有成功。

我有一组代表 3 个校区的数据。每个校区都有一些建筑物。第一个 for 循环穿过校园。嵌套的 for 循环遍历当前校园中的建筑物,并将单击事件绑定(bind)到它(这允许我以编程方式平移和缩放传单 map 。)

我创建了一个非常简化的 JSFiddle 来表示我正在尝试做的事情,这显示了问题。只有最后一个“校园”组中的建筑物保留了点击事件。

这是来自 JS Fiddle 的 JS 代码。 http://jsfiddle.net/scwutpno/3/

var campuses = {
"campus1": {
"buildings": {
"building1": {
"id": 1
},
"building2": {
"id": 2
},
"building3": {
"id": 3
}
},
"name": "Campus 1"
},
"campus2": {
"buildings": {
"building1": {
"id": 4
},
"building2": {
"id": 5
},
"building3": {
"id": 6
}
},
"name": "Campus 2"
},
"campus3": {
"buildings": {
"building1": {
"id": 7
},
"building2": {
"id": 8
},
"building3": {
"id": 9
}
},
"name": "Campus 3"
}
};

var buildingLinksContainer = document.getElementById("building-list");

function buildExternalLinks() {

for (var campus in campuses) {
var container,
item;


if (buildingLinksContainer !== null) {
buildingLinksContainer.innerHTML += '<div class="building-links" id="' + campus + '-buildings">' +
'<div class="building-links__campus-name">' + campuses[campus].name + '</div></div>';

container = document.getElementById(campus + '-buildings');
}


for (var building in campuses[campus].buildings) {

item = container.appendChild(document.createElement('li'));
item.innerHTML = 'Building ' + campuses[campus].buildings[building].id;

item.addEventListener("click", function () {
alert('clicked!');
});
}

}
}

buildExternalLinks();

我尝试将点击事件放入自调用闭包中,但我不认为点击事件内的数据有问题。它是应用点击事件的节点。我不知道是否因为我使用的是嵌套 for 循环,所以我需要某种嵌套闭包概念?

很想看看这个问题是如何解决的。我已经通过在 for 循环中使用闭包克服了这个问题,但是这个嵌套的 for 循环让我难住了。

最佳答案

问题在于,每次附加到“buildingLinksContainer”元素时,您的代码都会重写 DOM。每次您的代码使用“+=”附加到“buildingLinksContainer”的innerHTML 时,都会从头开始创建DOM。之前在“buildingLinksContainer”内具有事件监听器的所有元素都将创建为没有任何事件监听器的新元素。

仅在最后一次迭代中,当 DOM 之后没有被拆除时,事件监听器才会保留。并且由于在最后一次迭代中仅创建了最后三个 li 元素,因此只有它们具有事件监听器。

罪魁祸首:

buildingLinksContainer.innerHTML += '<div class="building-links" id="' + campus + '-buildings">' +
'<div class="building-links__campus-name">' + campuses[campus].name + '</div></div>';

我已经以一种有效的方式重写了您的解决方案(具有更好的性能和标记)

var buildingLinksContainer = document.getElementById("building-list");

function buildExternalLinks(campuses, rootElement) {

var ul = document.createElement('ul'),
li = document.createElement('li'),
h1 = document.createElement('h1'),
list = document.createDocumentFragment();

for(var campus in campuses) {
if(campuses.hasOwnProperty(campus)) {
var c = ul.cloneNode(false);
c.classList.add('building-links');
c.setAttribute('id', campus+'-buildings');

var name = h1.cloneNode(false);
name.appendChild(document.createTextNode(campuses[campus].name));

c.appendChild(name);

for(var building in campuses[campus].buildings) {
if(campuses[campus].buildings.hasOwnProperty(building)) {
var b = li.cloneNode(false);
var text = 'Building ' + campuses[campus].buildings[building].id;
b.appendChild(document.createTextNode(text));
b.addEventListener('click', function(event) {
alert(event.target.innerHTML);
});

c.appendChild(b);
}
}
}

list.appendChild(c);
}

rootElement.appendChild(list);
}

buildExternalLinks(campuses, buildingLinksContainer);

我还更新/ fork 了你的JSFiddle .

关于javascript - 将 click 事件绑定(bind)到在嵌套 for 循环中创建的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27518874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com