动态按钮上的JS事件监听器

时间:2018-05-16 13:27:47

标签: javascript

想知道为什么当添加多个动态按钮时,他们的toggle bg颜色监听器不能始终如一地工作。

如果我添加让我们说3个按钮,则按钮1和按钮1的监听器3按钮2赢了,



//document.ready
function ready(fn) {
  if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

//event listener on dynamic buttons not in DOM
ready(function() {
  document.querySelector('.makeB').addEventListener('click', function() {
    var btn = document.createElement("button");
    var t = document.createTextNode("toggle bg");
    btn.appendChild(t);
    document.body.appendChild(btn);
    btn.classList.add('elis');

    var newBtns = document.querySelectorAll('.elis');
    newBtns.forEach(function(i) {
      i.addEventListener('click', function() {
        document.body.classList.toggle('bg');
      })
    })
  })
})

.bg {
  background: red;
}

<button class="makeB">create button</button>
&#13;
&#13;
&#13;

研究了一些冒泡&amp;事件委托选项,看看是否有帮助(类似于jquery方法$(document).on( eventName, selector, function(){} );,但没有运气)

如何使动态按钮始终如一地工作以及当前情况的问题是什么?

只有JS(没有jQuery)。

3 个答案:

答案 0 :(得分:2)

//document.ready
function ready(fn) {
  if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

//event listener on dynamic buttons not in DOM
ready(function() {
  document.querySelector('.makeB').addEventListener('click', function() {
    var btn = document.createElement("button");
    var t = document.createTextNode("toggle bg");
    btn.appendChild(t);
    document.body.appendChild(btn);
    btn.classList.add('elis');
    btn.addEventListener('click', function() {
      document.body.classList.toggle('bg');
    })
  })
})
.bg {
  background: red;
}
<button class="makeB">create button</button>

答案 1 :(得分:1)

他们确实有效。问题是你每次添加一个按钮时只是添加更多的监听器,所以当任何特定按钮上有一定数量的监听器时,它们看起来就像它们一样。只需在按钮中添加一个监听器,然后再将其放入文档中。

答案 2 :(得分:1)

简化代码的另一种方法是使用事件委派。只需将click事件监听器添加到正文或其他封闭容器(可能是最接近的容器)中,并仅在event.target是您的某个按钮时执行其代码。

这样你就可以跳过那个一遍又一遍地向同一个按钮添加事件监听器的部分。

&#13;
&#13;
function ready(fn) {
  if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

document.body.addEventListener('click', event => {
  if (event.target.className === 'elis') {
    document.body.classList.toggle('bg');
  }
});

ready(function() {
  document.querySelector('.makeB').addEventListener('click', function() {
    const btn = document.createElement("button");
    btn.textContent = "toggle bg";
    btn.classList.add('elis')
    document.body.appendChild(btn);
  })
})
&#13;
.bg {
  background: red;
}
&#13;
<button class="makeB">create button</button>
&#13;
&#13;
&#13;