2016-10-04 88 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:找不到任何東西,但肯定有重複。 –