在迭代过程中添加点击事件监听器



我正试图在for循环中为一堆新创建的div添加一个点击事件侦听器。我遇到的问题是,只有最后一个div保留其事件侦听器。我读过关于闭包的文章,也读过其他几篇帖子、问题及其答案,据我所知,我已经正确设置了它。但它对我来说仍然不起作用。只有最后一个要迭代的div接收事件侦听器。

function edit_entry(k) {
wrd_input.value = k;
def_input.value = lexicon[k][1];
wrd_input.onkeyup();
delete lexicon[k];
rewrite_entries();
}
function rewrite_entries(keys = null) {
if (keys === null) { keys = []; }
let sorted_keys = sort_lex_keys();
lex_body.style.color = 'rgb(200, 200, 200)';
lex_body.innerHTML = '';
sorted_keys.forEach((key) => {
if (!keys.length || keys.includes(key)) {
lex_body.innerHTML += 
`<div class='lex-entry' id=${key}><i>${key}</i>n<p class='pronunciation'>${lexicon[key][0]}</p>${lexicon[key][1]}</div>n`;
let entry = document.getElementById(key)
entry.addEventListener('click', edit_entry.bind(this, key) );
}
});
}

上述相关代码的当前状态。如果有人知道这个问题,那将是非常有帮助的。如果相关,此代码通过Electron(17.0.0(运行

尝试使用匿名箭头函数而不是绑定的解决方案:

entry.addEventListener('click', () => edit_entry(key) );

产生相同的结果。


更新:更改某个内容的.ninnerHTML属性显然会剥离所有事件侦听器。因此,解决方案只是在js中完全创建元素,将其添加到容器中,然后添加监听器。对forEach循环的这种更改解决了问题:

sorted_keys.forEach((key) => {
if (!keys.length || keys.includes(key)) {
let entry = document.createElement('div');
entry.className = 'lex-entry';

let word = document.createElement('p');
word.appendChild( document.createTextNode(key) );
word.style.fontStyle = 'italic';

let pron = document.createElement('p');
pron.className = 'pronunciation';
pron.appendChild( document.createTextNode(lexicon[key][0]) );

let defn = document.createTextNode(lexicon[key][1]);

entry.append(word, pron, defn);
entry.addEventListener('click', () => edit_entry(key) );
lex_body.appendChild(entry);

所以我想到了一些事情:

首先,edit_entry.bind(this, key);:你确定this指向你想要的吗?它应该指向window对象。此外,是否有任何理由为该特定函数绑定上下文?

其次是innerHTML:一般不鼓励直接使用innerHTML。我不知道当浏览器布局更改为innerHTML时,当您调用getElementById时,div可能不在页面上。作为替代方案,您可以尝试document.createElement("div"),相应地设置其属性,最后将其附加到lex_body

编辑

来自mdn:

请注意,使用innerHTML附加html元素(例如el.innerHTML+="链接"(将导致删除任何以前设置的事件侦听器。也就是说,在以这种方式附加任何HTML元素之后,您将无法侦听以前设置的事件侦听器。

我认为每次用this绑定函数都会覆盖每次的绑定,这应该是你只得到最后一个事件的原因。

forEachlambda内部,this关键字指的是调用forEach而不是rewrite_entries函数的内部类。尝试不绑定呼叫,如下所示:

entry.addEventListener('click', () => edit_entry(key) );

相关内容

  • 没有找到相关文章

最新更新