我遇到了 es6 类和事件监听器的问题? [复制]

Posted

技术标签:

【中文标题】我遇到了 es6 类和事件监听器的问题? [复制]【英文标题】:I am having issues with es6 classes and event listeners? [duplicate] 【发布时间】:2017-02-13 01:09:39 【问题描述】:

现在已经回答了。不是 ES6 或事件监听器的问题,而是 innerHTML 是如何工作的。它正在删除所有 html (破坏侦听器),然后将 html 添加回来,只附加了最新的侦听器。谢谢。

基本上我遇到了 ES6 类和事件监听器的问题。或者这很可能只是我对整个事情的理解。

我正在动态创建名为“Thing”的同一类的 5 个实例。每个“事物”都会将一段 html 写入包含一个按钮的 DOM,并添加一个事件侦听器来处理点击。正在使用 document.querySelector 选择元素,并基于名为“indexNumber”的数据属性来唯一标识每个按钮。

由于每件事都是它自己的实例,我想每个按钮都可以工作,但只有最后一个按钮可以工作。为什么一个类的一个实例会覆盖另一个?

谁能解释这里发生了什么?

HTML

<h1>Things</h1>
<span class="output"></span>
<div class="thingHolder"></div>

JS(通天塔)

class Thing 
  constructor(index) 
    this.Index = index;
    this.html = '<div class="thing" data-index-number="'+ index +'">Thing ' + index + '<button type="button">Click Me!</button></div>';
    this.renderDom();
  
  renderDom()
    const thingHolder = document.querySelector(".thingHolder");
    thingHolder.innerHTML += this.html;

     this.addEventListeners();
  

  addEventListeners()
    const button = document.querySelector('.thingHolder .thing[data-index-number="' + this.Index + '"] button');

    button.addEventListener("click", () => 
      this.doSomething()
    , false);
  

  doSomething()
    const output = document.querySelector(".output");
    output.innerHTML = 'You clicked thing #' + this.Index;
    console.log('You clicked thing #' + this.Index)
  


for(var i = 0; i < 5; i++) 
 var thing = new Thing(i);

【问题讨论】:

【参考方案1】:

问题与 ES6 或 javascript 无关。

thingHolder.innerHTML += this.html;

销毁重新创建thingHolder 的所有现有子级。在该过程中,现有的事件处理程序将被销毁。

您应该使用 DOM API 创建和附加新元素,而不是创建 HTML 和使用 innerHTML

例子:

var div = document.createElement('div');
div.addEventListener('click', () =>  ... );

// ...
thingHolder.appendChild(div);

【讨论】:

如果您认为thingHolder.innerHTML += this.html;thingHolder.innerHTML = thingHolder.innerHTML + this.html; 相同,可能更容易理解。 我们没有一个规范的骗子吗? @Bergi:找不到任何东西,但肯定有重复。 @FelixKling 我不得不联系我的骗子名单,搜索确实没有帮助 我使用 innerHTML 的原因是因为我正在做一些 mustache.js 模板,它生成一个 html 字符串而不是节点元素。 insertAdjacentHTML 确实有效。【参考方案2】:

当您使用thingHolder.innerHTML += html 时,容器中的旧对象将被删除并重新创建,但没有它们的事件侦听器。因此,每次以这种方式插入新节点时,您都​​会重新创建它们。

第一个按钮是唯一有效的事实是因为您仅在删除所有其他事件之后将事件附加到您在父级中遇到的第一个元素(使用 querySelector)。

所以解决方案是create your elements with JS(或 Babel 中使用的任何东西)而不是使用 innerHTML。

【讨论】:

"或 Babel 中使用的任何东西" JavaScript ;) @FelixKling 我不知道。现在的网络中使用了非常晦涩的东西 XP

以上是关于我遇到了 es6 类和事件监听器的问题? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在 es6 中,创建一个带有回调的事件监听器到一个可迭代对象中

input 标签的监听事件总结

es6 添加事件监听

如何使用 ES6 箭头函数从 jQuery on() 事件中获取元素? [复制]

如何使用事件侦听器复制DOM节点?

如何使用ES6类添加事件侦听器并在画布中移动对象?