Javascript: 事件处理多个动态元素

Javascript: Event handling multiple dynamic elements

我正在寻找一种更好的方法来处理页面上可动态显示的多个元素的事件。 目前我正在使用此代码:

var myToolbar = document.createElement('div');
setInterval(function () {
    for (let textField of document.querySelectorAll('textarea[name="text"]:not(.modified)')) {
        textField.classList.add('modified');
        textField.addEventListener('focus', function () {
            textField.insertAdjacentElement('beforebegin', myToolbar);
        });
    }
}, 1000);

这很好地完成了我的任务,但是一直有一个间隔 运行 似乎很笨拙。

您应该了解呈现给网页的组件及其在应用程序中的状态。如果不是,那么你的设计模式是错误的,需要多加思考。你现在所做的一切都是灾难的根源。在 setInterval 中随意添加事件侦听器而不清理它们——有内存泄漏的味道。

您最初呈现给网页的组件应该有自己的事件侦听器来处理您调用的 "dynamic" 元素出现。这些动态元素的出现要么是因为您的应用程序将它们放在那里,要么是用户做了一些事情使它们出现在那里。这两件事都可以在您的应用程序状态中进行跟踪和维护。

据说为了避免出现您所描述的问题,您需要将应用程序状态的控制权转给您的代码,而不是 DOM 的状态。这将使设置事件侦听器和在需要时删除事件侦听器变得容易得多。

因此,除非您对 ContentEditable 区域做一些花哨的事情,否则您应该重新考虑您的应用程序的设计。

您可以使用 MutationObserver。示例:

setInterval(() => {
  const allDivs = document.querySelectorAll('div');
  const randomDiv = allDivs[Math.floor(Math.random() * allDivs.length)];
  randomDiv.appendChild(document.createElement('div'));
}, 1000);

const obs = new MutationObserver(track);
obs.observe(document.body.children[0], { childList: true, subtree: true });

function track(mutations) {
  mutations.forEach((mutation) => {
    mutation.addedNodes.forEach(addedNode => {
      if (addedNode.tagName === 'DIV') addedNode.classList.add('found');
    });
  });
}
div {
  border: 1px solid black;
  background-color: white;
  height: 20px;
  width: 20px;
}
.found {
  background-color: yellow;
}
<div>
</div>

对于你的特殊情况,你想找到新的 textarea[name="text"]s,所以你会改为测试:

if (addedNode.tagName === 'TEXTAREA' && addedNode.name === 'text') {
  // ...
}