2016-10-04 89 views
0

现在已经回答了。不是ES6或事件监听器的问题,而是innerHTML如何工作。它将删除所有的html(打破听众),然后添加html,只添加最新的侦听器。谢谢。我遇到了es6类和事件监听器的问题?

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

我正在动态创建5个同名类的实例,名为'Thing'。每个'Thing'都会将一段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

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

第一个按钮是唯一可以工作的事实是因为您仅在您移除所有其他事件之后将事件仅附加到在父级内部遇到的第一个元素(使用querySelector)。

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

+2

* * JavaScript的 “或什么是通天使用”;) –

+0

@FelixKling我不知道。非常隐晦的事情现在在网络中使用XP – germanfr

2

该问题与ES6或JavaScript无关。

thingHolder.innerHTML += this.html; 

破坏重新thingHolder现有的所有儿童。在那个过程中,现有的事件处理程序被销毁。

而不是创建HTML和使用innerHTML你应该使用DOM API来创建和追加新的元素。

例子:

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

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

如果您认为'thingHolder.innerHTML + = this.html;'与'thingHolder.innerHTML = thingHolder.innerHTML + this.html'相同可能会更容易理解; 。 – Nit

+0

难道我们没有一个规范的欺骗吗? – Bergi

+0

@Bergi:找不到任何东西,但肯定有重复。 –