【问题标题】:Onclick button is working only in first listOnclick 按钮仅在第一个列表中有效
【发布时间】:2021-02-17 12:40:19
【问题描述】:
我想复制列表项及其所有子元素,这是我的示例代码。仅在第一个列表中,单击时有效,重复列表的按钮无效
document.querySelectorAll(".btnMe").forEach(el => {
el.addEventListener('click', () => {
var myDiv = document.querySelector(".list");
var divClone = myDiv.cloneNode(true);
document.querySelector('#lists').appendChild(divClone);
})
})
<ul id="lists">
<li class="list">
<p>Test</p>
<button class="btnMe">Click Me</button>
</li>
</ul>
【问题讨论】:
标签:
javascript
onclick
duplicates
【解决方案1】:
使用事件委托代替处理绑定事件。
var wrapper = document.querySelector("#lists")
wrapper.addEventListener('click', (evt) => {
var btnClicked = evt.target.closest("button.btnMe");
if (btnClicked) {
var myDiv = document.querySelector(".list");
var divClone = myDiv.cloneNode(true);
wrapper.appendChild(divClone);
}
})
<ul id="lists">
<li class="list">
<p>Test</p>
<button class="btnMe">Click Me</button>
</li>
</ul>
【解决方案2】:
cloneNode 复制所有节点的属性和值,但不复制使用addEventListener() 添加的事件侦听器。所以你需要重新添加这些事件监听器。
您的document.querySelectorAll() 仅在您第一次加载页面时运行,因此一个简单的document.querySelector() 应该可以工作,在这种情况下您甚至不需要forEach() 方法。
如果我理解正确,您想克隆您单击的按钮所在的元素。如果button 是li 的子元素,那么您可以克隆node.parentNode。克隆之后,你可以给它添加事件监听函数。
function cloneParent() {
let clone = this.parentNode.cloneNode(true);
clone.querySelector('.btnMe').addEventListener('click', cloneParent);
document.querySelector('#lists').appendChild(clone);
}
document.querySelector('.btnMe').addEventListener('click', cloneParent);
<ul id="lists">
<li class="list">
<p>Test</p>
<button class="btnMe">Click Me</button>
</li>
</ul>
如@epascarello 所述,仅添加一个事件侦听器并使用事件委托应该是首选方式。