我正在编写一个Web应用程序作为一项家庭作业项目,该项目使用websocket接收来自服务器的消息,并使用handlebars.js在html上显示它们。
我正在尝试使用以下代码实现删除消息的功能:
document.addEventListener('DOMContentLoaded', () => {
...
let message_container = document.querySelector("#message_container");
const message_template = Handlebars.compile(document.querySelector("#message_template").innerHTML);
const delete_button_template = Handlebars.compile(document.querySelector("#delete_button_template").innerHTML);
function addDeleteButton(id) {
let con = delete_button_template({"message_id": id}); //line #1
document.querySelector("#content_" + id).innerHTML += con;
document.querySelector("#delete_button_" + id).onclick = function () {
const msg_id = event.target.dataset.message_id;
const msg = document.querySelector("#message_" + msg_id);
const blank = document.querySelector("#message_" + msg_id + "_newline");
msg.parentElement.removeChild(msg);
blank.parentElement.removeChild(blank);
}
}
将消息添加到DOM的功能很简单:
function newMessage(i) {
let msg = message_template({
"message_id": i.message_id,
"username": ...,
"timestamp": ...,
"content": ...
});
message_container.innerHTML += msg;
addDeleteButton(i.message_id);
}
删除按钮的handlebars.js模板已插入HTML,如下所示:
<button id="delete_button_{{ message_id }}" data-message_id="{{ message_id }}" class="btn btn-primary">
Delete
</button>
但是,每次我向DOM添加新消息(包括删除按钮)时,所有先前的按钮都会丢失其onclick()事件侦听器。chrome检查器清楚地显示了这一点,它发生在第1行:
第四个按钮注册了一个事件侦听器。
一个明确的解决方法是将onclick调用嵌入html属性。但是为什么我不能像给定代码那样注册事件监听器?
问题在于以下行:
message_container.innerHTML += msg;
我们正在使用把手生成一个新的HTML字符串,并将其存储到msg
变量中。然后,我们要将该新HTML附加到#message_container
DOM元素。
但是,message_container.innerHTML += msg
也不能简单地添加我们的新的HTML的#message_container
,相反,它替换所有的后代DOM节点的 #message_container
!
发生的故障是:
#message_container
DOM中的后代节点,并被字符串化为HTML字符串。msg
被连接到此新HTML字符串的末尾。innerHTML
的#message_container
。这里的重要部分是更换。当innerHTML
of#message_container
被替换时,其所有后代节点都被替换。因此<button>
,您先前附加的onclick
侦听器的所有都已从DOM中删除。
防止替换#message_container
每次要添加的所有子项的一种<button>
方法是使用Node.appendChild()
API。结果代码如下所示:
// message_container.innerHTML += msg; // TODO: Replace this line with the below.
const node = document.createElement('div');
node.innerHTML = msg;
message_container.appendChild(node);
我创建了一个小提琴供参考。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句