为了账号安全,请及时绑定邮箱和手机立即绑定

使用Handlebar.js模板为多个按钮添加onclick事件监听,只有最后一个有效

使用Handlebar.js模板为多个按钮添加onclick事件监听,只有最后一个有效

千万里不及你 2024-01-03 15:22:32
我正在编写一个 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事件消失了。一个明确的解决方法是将 onclick 调用嵌入到 html 属性中。但为什么我不能像给定的代码那样注册事件侦听器?
查看完整描述

1 回答

?
富国沪深

TA贡献1790条经验 获得超9个赞

问题在于以下行:

message_container.innerHTML += msg;

我们使用 Handlebars 生成一个新的 HTML 字符串,并将其存储到msg变量中。然后我们想要将新的 HTML附加#message_container到DOM 元素。

然而,它并不是message_container.innerHTML += msg简单地将我们的新 HTML 附加到,而是替换!的所有后代 DOM 节点。#message_container #message_container

发生的情况的细分是:

  • 我们获取 DOM 中的后代节点#message_container,并将其字符串化为 HTML 字符串。

  • msg连接到这个新 HTML 字符串的末尾。

  • 新的 HTML字符串取代innerHTML#message_container.

这里重要的部分是替换。当innerHTMLof#message_container被替换时,它的所有后代节点都被替换<button>因此,您之前附加侦听器的所有sonclick都已从 DOM 中删除。

防止#message_container每次添加 a 时替换所有子级的一种方法<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);

我创建了一个小提琴供参考。



查看完整回答
反对 回复 2024-01-03
  • 1 回答
  • 0 关注
  • 50 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信