要从节点上删除元素而不删除关联事件吗?

问题描述 投票:0回答:1

我一直在从事html / css / javascript'etch-a-sketch'风格的项目。简而言之,我有一个带有mouseenter事件的div元素网格:

const fillInGrid = document.querySelectorAll(".gridSquares");
fillInGrid.forEach((div) => {
    div.addEventListener('mouseenter', (e) => {
        div.style.backgroundColor = 'black';
    });
});

在项目中,我有一个重置按钮,该按钮从网格中删除子元素,并用新的div替换它们,两个提示,其中用户指定的行和列数会生成一个新的网格:

const resetButton = document.querySelector("#reset");
resetButton.addEventListener('click', (e) => {
        const resetEvent = document.getElementById('container');
        while (resetEvent.lastElementChild) {
            resetEvent.removeChild(resetEvent.lastElementChild);
        };
        newGrid();
    }
);

但是,在单击重置并为新网格选择尺寸后,会生成该网格,但是该网格对mouseenter事件失去响应,因为我假设该事件与div一起被删除了,有没有一种方法可以重新添加事件或可以删除​​div而没有相关事件的方法替代方法?

指向演示该问题的代码笔的链接:https://codepen.io/MaBuCode/pen/eYpjwOV

javascript html css dom events
1个回答
0
投票

除了可以在子元素上添加多个事件监听器之外,还可以在包含元素上添加单个事件监听器。这样,您的代码将变得更高效,并且还可以捕获在动态(新创建的)元素上触发的任何事件。

您需要用支持mouseentermouseover事件替换bubbling事件。

这是添加和替换mouseenter事件的代码:

// // One event listener to rule them all:
document.getElementById("container").addEventListener('mouseover', (e)=>{

  if ( e.target.classList.contains('gridSquares')){
    e.target.style.backgroundColor = 'black';    
  }

});

您现在可以摆脱单个div事件侦听器:

fillInGrid.forEach((div) => {
    div.addEventListener('mouseenter', (e) => {
        div.style.backgroundColor = 'black';
    });
});

Codepen Demo


提示:我还重构了'gridCreator'函数以减少appendChild操作的数量,而是将其替换为简单的字符串连接以使代码更具性能:

function gridCreator(gridSize) {
    let content = "";
    for (let i = 0; i < gridSize; i++) {
      content += "<div class='gridSquares'></div>";
    }
    document.getElementById("container").innerHTML = content;
}

通过使用上述方法,您还可以省略那些在resetButton代码中删除.container子元素的代码。

© www.soinside.com 2019 - 2024. All rights reserved.