在 DOM(在 javascript 中)中显示后,无法在 createElement()(按钮)上使用 addEventListener()
Cannot use addEventListener() on a createElement() (a button) after displaying it in the DOM (in javascript)
我最近在创建一个Javascript框架,我面临两个我完全不明白的问题。当我在 Javascript 中创建一个带有 createElement()
的新按钮时,我不能同时将它放在几个元素中而不终止“点击”事件(如果这是一个 id
,它有效)。
(注:"button.onclick = function()"
也不行)
这是代码:(我不想使用任何库)
function createButton() {
var button = document.createElement("button");
button.innerHTML = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
// Problem Two : If I click on the button, nothing happends
button.addEventListener("click", function(e) {
alert(e.target);
}, false);
var clas = document.getElementsByClassName("test");
Array.from(clas).forEach(element => {
element.appendChild(button);
element.innerHTML += ""; // First problem : If I don't do this, the button does not appear in the first div. I have no idea why !
});
}
createButton();
body {
margin: 0;
padding: 0;
display:flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bug</title>
</head>
<body>
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
</body>
</html>
有2个问题:
element.innerHTML += "";
,其中 element
指的是按钮的 父级 ,将强制父级 re-parse 其内容从他们的 HTML 字符串,从而破坏子元素上的任何现有处理程序。侦听器附加到的元素将从 DOM 中删除并替换为不同的元素;新的没有监听器
当您执行 appendChild
时,如果要追加的元素已经存在于 DOM 中,它将在追加到新元素之前从它之前存在的位置移除地点。由于您只执行 document.createElement('button')
一次,没有 innerHTML += ''
,当按钮附加到第二个时,按钮将从其第一个位置移除。
改为在循环内创建按钮,两个问题都解决了。
function createButton() {
var clas = document.getElementsByClassName("test");
Array.from(clas).forEach(element => {
var button = document.createElement("button");
button.innerHTML = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
// Problem Two : If I click on the button, nothing happends
button.addEventListener("click", function(e) {
alert(e.target);
}, false);
element.appendChild(button);
});
}
createButton();
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
或者,让代码更漂亮一点:
function createButton() {
for (const parent of document.querySelectorAll('.test')) {
const button = parent.appendChild(document.createElement("button"));
button.textContent = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
button.addEventListener("click", function(e) {
console.log(e.target);
});
}
}
createButton();
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
你的按钮是单实例,重复调用
element.appendChild(button);
只需在DOM中重复移动它。
您随后致电
element.innerHTML += "";
从 DOM 中删除该引用,而是从其 outerHTML
中创建一个新的 button
。这也是您添加的事件侦听器丢失的地方。
如果您需要多个按钮,您还需要创建多个 按钮。
我强烈建议你委托和克隆
我想我几天前已经为您发布了这个答案
function createButton() {
const button = document.createElement("button");
button.classList.add("redwhite");
button.innerHTML = "YOOOO";
[...document.querySelectorAll(".test")].forEach(element => {
element.appendChild(button.cloneNode(true));
});
}
createButton();
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("redwhite")) {
console.log(tgt.closest("div").id)
}
})
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
.redwhite {
background-color: red;
color: white;
}
<div id="container">
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
</div>
我最近在创建一个Javascript框架,我面临两个我完全不明白的问题。当我在 Javascript 中创建一个带有 createElement()
的新按钮时,我不能同时将它放在几个元素中而不终止“点击”事件(如果这是一个 id
,它有效)。
(注:"button.onclick = function()"
也不行)
这是代码:(我不想使用任何库)
function createButton() {
var button = document.createElement("button");
button.innerHTML = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
// Problem Two : If I click on the button, nothing happends
button.addEventListener("click", function(e) {
alert(e.target);
}, false);
var clas = document.getElementsByClassName("test");
Array.from(clas).forEach(element => {
element.appendChild(button);
element.innerHTML += ""; // First problem : If I don't do this, the button does not appear in the first div. I have no idea why !
});
}
createButton();
body {
margin: 0;
padding: 0;
display:flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bug</title>
</head>
<body>
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
</body>
</html>
有2个问题:
element.innerHTML += "";
,其中element
指的是按钮的 父级 ,将强制父级 re-parse 其内容从他们的 HTML 字符串,从而破坏子元素上的任何现有处理程序。侦听器附加到的元素将从 DOM 中删除并替换为不同的元素;新的没有监听器当您执行
appendChild
时,如果要追加的元素已经存在于 DOM 中,它将在追加到新元素之前从它之前存在的位置移除地点。由于您只执行document.createElement('button')
一次,没有innerHTML += ''
,当按钮附加到第二个时,按钮将从其第一个位置移除。
改为在循环内创建按钮,两个问题都解决了。
function createButton() {
var clas = document.getElementsByClassName("test");
Array.from(clas).forEach(element => {
var button = document.createElement("button");
button.innerHTML = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
// Problem Two : If I click on the button, nothing happends
button.addEventListener("click", function(e) {
alert(e.target);
}, false);
element.appendChild(button);
});
}
createButton();
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
或者,让代码更漂亮一点:
function createButton() {
for (const parent of document.querySelectorAll('.test')) {
const button = parent.appendChild(document.createElement("button"));
button.textContent = "YOOOO";
button.style.backgroundColor = "red";
button.style.color = "white";
button.addEventListener("click", function(e) {
console.log(e.target);
});
}
}
createButton();
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
你的按钮是单实例,重复调用
element.appendChild(button);
只需在DOM中重复移动它。
您随后致电
element.innerHTML += "";
从 DOM 中删除该引用,而是从其 outerHTML
中创建一个新的 button
。这也是您添加的事件侦听器丢失的地方。
如果您需要多个按钮,您还需要创建多个 按钮。
我强烈建议你委托和克隆
我想我几天前已经为您发布了这个答案
function createButton() {
const button = document.createElement("button");
button.classList.add("redwhite");
button.innerHTML = "YOOOO";
[...document.querySelectorAll(".test")].forEach(element => {
element.appendChild(button.cloneNode(true));
});
}
createButton();
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("redwhite")) {
console.log(tgt.closest("div").id)
}
})
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgba(30, 30, 30, 0.2);
}
button {
cursor: pointer;
width: 80px;
height: 50px;
padding: 10px;
}
.redwhite {
background-color: red;
color: white;
}
<div id="container">
<div class="test" id="1" style="padding: 50px;">
<span>1</span>
</div>
<div class="test" id="2" style="padding: 50px;">
<span>2</span>
</div>
</div>