Javascript 事件侦听器未按预期做出反应 - 某些事件未触发
Javascript event listener does not react as expected - some events are not fired
我得到了以下简单页面。
<style>
#notifier {
position: fixed;
width: 320px;
bottom: 0;
left: 0;
padding: 10px;
}
#notification-silo {
width: 300px;
height: 100%;
position: relative;
}
#notification-silo .notification {
position: absolute;
bottom: 0;
width: 300px;
background-color: #fff;
box-shadow: 2px 2px 8px 2px #666;
}
#notification-silo .header {
background-color: #1266AB;
color: #fff;
padding: 5px;
}
#notification-silo .error .header {
background-color: #1266AB;
}
#notification-silo .warning .header {
background-color: #ff8f5f;
}
#notification-silo .header .title {
width: 260px;
display: inline-block;
}
#notification-silo .header .close-wrapper {
display: inline-block;
}
#notification-silo .header .close-wrapper button {
height: 25px;
width: 25px;
background-color: #2277bb;
border: 0;
color: #ff8f5f;
border-radius: 50%;
}
#notification-silo .warning .header .close-wrapper button {
background-color: #ffaa77;
color: #2277bb;
}
#notifier .body {
padding: 5px;
border: 1px solid lightgray;
}
</style>
<div id="notifier">
<div id="notification-silo">
</div>
</div>
<script>
function show(html) {
let notification, notificationArray, body, closeButton, existingNotificationHeights, sum, bottom, notification_template, siloElement, marginBetweenNotifications;
siloElement = document.querySelector("#notification-silo");
notification_template = `<div class="notification">
<div class="header">
<div class="title">Message</div>
<div class="close-wrapper">
<button>X</button>
</div>
</div>
<div class="body"></div>
</div>`;
marginBetweenNotifications = 10;
// calculate position
existingNotificationHeights = [...siloElement.children].map(notification => notification.offsetHeight);
sum = existingNotificationHeights.length ? existingNotificationHeights.reduce((a, b) => a + b) : 0;
bottom = sum + existingNotificationHeights.length * marginBetweenNotifications;
// creat elements by update innerHTML
siloElement.innerHTML += notification_template.trim();
notificationArray = [...siloElement.querySelectorAll(".notification")];
notification = notificationArray[notificationArray.length - 1];
notification.style.bottom = bottom + "px";
body = notification.querySelector(".body");
body.innerHTML += html;
// add event listener to close button
closeButton = notification.querySelector(".close-wrapper button");
closeButton.addEventListener("click", (ev) => {
console.log("click is fired");
});
};
show("System message 1");
show("System message 2");
show("System message 3");
show("System message 4");
show("System message 5");
</script>
意思是通过 show(msg) 函数创建简单的通知消息。这是有趣的部分 - 当创建一些消息并尝试将事件侦听器添加到它们的关闭按钮时,只有最后一个按钮获得侦听器并实际侦听点击事件。所有其他关闭按钮不会对鼠标单击做出反应。你能帮我理解为什么吗?
只需要获取关闭按钮引用对象
show("System message 1");
show("System message 2");
show("System message 3");
show("System message 4");
show("System message 5");
[].forEach.call(document.querySelectorAll("#notification-silo button.close-wrapper"),function(el){
el.addEventListener("click",function(ev){
var targetElement = ev.target || ev.srcElement;
console.log(targetElement); //reference of button...
});
});
或
<div class="close-wrapper">
<button onClick="Close(this)">X</button>
</div>
或作为一种标准方式完美不使用静态 html 模板字符串使用动态纯 JavaScript 基于元素创建方法
示例:
let mainDiv = document.querySelector("#notification-silo");
let aTag = document.createElement('a');
aTag.innerHTML = "CLOSE TEXT....";
aTag.addEventListener("click", (ev) => {
console.log("click is fired");
});
mainDiv.appendChild(aTag);
引用 ProGu:
I guess siloElement.innerHTML += notification_template.trim()
wipes
off the html content and re-assigned again, so previous events are
removed.
我得到了以下简单页面。
<style>
#notifier {
position: fixed;
width: 320px;
bottom: 0;
left: 0;
padding: 10px;
}
#notification-silo {
width: 300px;
height: 100%;
position: relative;
}
#notification-silo .notification {
position: absolute;
bottom: 0;
width: 300px;
background-color: #fff;
box-shadow: 2px 2px 8px 2px #666;
}
#notification-silo .header {
background-color: #1266AB;
color: #fff;
padding: 5px;
}
#notification-silo .error .header {
background-color: #1266AB;
}
#notification-silo .warning .header {
background-color: #ff8f5f;
}
#notification-silo .header .title {
width: 260px;
display: inline-block;
}
#notification-silo .header .close-wrapper {
display: inline-block;
}
#notification-silo .header .close-wrapper button {
height: 25px;
width: 25px;
background-color: #2277bb;
border: 0;
color: #ff8f5f;
border-radius: 50%;
}
#notification-silo .warning .header .close-wrapper button {
background-color: #ffaa77;
color: #2277bb;
}
#notifier .body {
padding: 5px;
border: 1px solid lightgray;
}
</style>
<div id="notifier">
<div id="notification-silo">
</div>
</div>
<script>
function show(html) {
let notification, notificationArray, body, closeButton, existingNotificationHeights, sum, bottom, notification_template, siloElement, marginBetweenNotifications;
siloElement = document.querySelector("#notification-silo");
notification_template = `<div class="notification">
<div class="header">
<div class="title">Message</div>
<div class="close-wrapper">
<button>X</button>
</div>
</div>
<div class="body"></div>
</div>`;
marginBetweenNotifications = 10;
// calculate position
existingNotificationHeights = [...siloElement.children].map(notification => notification.offsetHeight);
sum = existingNotificationHeights.length ? existingNotificationHeights.reduce((a, b) => a + b) : 0;
bottom = sum + existingNotificationHeights.length * marginBetweenNotifications;
// creat elements by update innerHTML
siloElement.innerHTML += notification_template.trim();
notificationArray = [...siloElement.querySelectorAll(".notification")];
notification = notificationArray[notificationArray.length - 1];
notification.style.bottom = bottom + "px";
body = notification.querySelector(".body");
body.innerHTML += html;
// add event listener to close button
closeButton = notification.querySelector(".close-wrapper button");
closeButton.addEventListener("click", (ev) => {
console.log("click is fired");
});
};
show("System message 1");
show("System message 2");
show("System message 3");
show("System message 4");
show("System message 5");
</script>
意思是通过 show(msg) 函数创建简单的通知消息。这是有趣的部分 - 当创建一些消息并尝试将事件侦听器添加到它们的关闭按钮时,只有最后一个按钮获得侦听器并实际侦听点击事件。所有其他关闭按钮不会对鼠标单击做出反应。你能帮我理解为什么吗?
只需要获取关闭按钮引用对象
show("System message 1");
show("System message 2");
show("System message 3");
show("System message 4");
show("System message 5");
[].forEach.call(document.querySelectorAll("#notification-silo button.close-wrapper"),function(el){
el.addEventListener("click",function(ev){
var targetElement = ev.target || ev.srcElement;
console.log(targetElement); //reference of button...
});
});
或
<div class="close-wrapper">
<button onClick="Close(this)">X</button>
</div>
或作为一种标准方式完美不使用静态 html 模板字符串使用动态纯 JavaScript 基于元素创建方法
示例:
let mainDiv = document.querySelector("#notification-silo");
let aTag = document.createElement('a');
aTag.innerHTML = "CLOSE TEXT....";
aTag.addEventListener("click", (ev) => {
console.log("click is fired");
});
mainDiv.appendChild(aTag);
引用 ProGu:
I guess
siloElement.innerHTML += notification_template.trim()
wipes off the html content and re-assigned again, so previous events are removed.