我遇到es6类和事件监听器的问题?

时间:2016-10-04 18:43:53

标签: javascript html

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

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

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

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

有谁可以解释这里发生的事情?

HTML

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

JS(Babel)

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);
}

2 个答案:

答案 0 :(得分:2)

问题与ES6或JavaScript无关。

thingHolder

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

您应该使用DOM API来创建和追加新元素,而不是创建HTML并使用var div = document.createElement('div'); div.addEventListener('click', () => { ... }); // ... thingHolder.appendChild(div);

示例:

Table 1: SOURCE_SYSTEM 
ID  CODE    Source ID   Source Name
123 111 Monster Dice.com 
456 111 Dice    ABC COMPANY
456 888 Ticv    A2 systems
4566    999 MOnster hgtt solutions
789 222 Monster ABC COMPANY
985 222 Dice    Dice.com 

Table 2: TARGET_SYSTEM 
RECORDID    AI CL ID    Source Name Op Code
123 111 Dice.com    Secondary
456 111 ABC COMPANY Primary
789 222 ABC COMPANY Secondary
985 222 Dice.com    Primary

答案 1 :(得分:1)

当您使用<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.raviteja.youexample"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> 时,容器中的旧对象将被删除并重新创建,但没有它们的事件侦听器。因此,每次以这种方式插入新节点时都要重新创建它们。

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

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