使用Handlebar.js模板将onclick事件侦听器添加到多个按钮中,只有最后一个有效

小坂穗香

我正在编写一个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属性。但是为什么我不能像给定代码那样注册事件监听器?

76484

问题在于以下行:

message_container.innerHTML += msg;

我们正在使用把手生成一个新的HTML字符串,并将其存储到msg变量中。然后,我们要将该新HTML附加#message_containerDOM元素。

但是,message_container.innerHTML += msg不能简单地添加我们的新的HTML的#message_container,相反,它替换所有的后代DOM节点的 #message_container

发生的故障是:

  • 我们得到#message_containerDOM中的后代节点,并被字符串化为HTML字符串。
  • msg 被连接到此新HTML字符串的末尾。
  • 新的HTML字符串替换innerHTML#message_container

这里的重要部分是更换innerHTMLof#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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Javascript只有最后一个事件侦听器有效

来自分类Dev

将键侦听器或键绑定添加到使用ActionListener的JButton中

来自分类Dev

将键添加到多个数组,并使用另一个有序数组中的相应值按顺序填充该键的值

来自分类Dev

如何将事件侦听器添加到使用Jquery Event构造函数创建的Jquery Event中

来自分类Dev

(Java)使用for循环获取所有组合并添加到ArrayList,但是ArrayList仅最后添加一个

来自分类Dev

Onsen 2.0-使用Javascript将事件侦听器添加到Ons-Switch

来自分类Dev

如何使用express和handlebar或其他模板引擎在node.js中渲染rest api调用?

来自分类Dev

如何将ssl证书列表添加到使用Terraform for循环构造之一创建的alb侦听器列表中?

来自分类Dev

如何使用SQLite将一个表的count()添加到具有多个其他表的联接的SQL查询中?

来自分类Dev

如何使用react和typescript将事件侦听器添加到使用ref访问的div元素?

来自分类Dev

在点击处理程序中使用两个useState设置器时,只有一个有效

来自分类Dev

如何使用Redis将多个值添加到一个键中

来自分类Dev

将事件侦听器添加到使用Javascript从API捕获的动态生成的元素中

来自分类Dev

使用Lambda将侦听器添加到ObjectAnimator

来自分类Dev

如何将ssl证书列表添加到使用Terraform for循环构造之一创建的alb侦听器列表中?

来自分类Dev

将键侦听器或键绑定添加到使用ActionListener的JButton中

来自分类Dev

将键添加到多个数组,并使用另一个有序数组中的相应值按顺序填充该键的值

来自分类Dev

使用Django / South将ManyToManyField添加到现有模型中给我一个错误

来自分类Dev

使用JS / JQuery按类选择文档后,将onclick事件添加到按钮

来自分类Dev

这是使用侦听器的更有效方法:使用匿名类或实现列表器

来自分类Dev

使用while循环创建多个按钮,但使用.onclick函数时只有第一个按钮响应

来自分类Dev

与handlebar.js循环

来自分类Dev

使用Underscore.js具有动态表单输入的Handlebar.js模板-Zendesk App

来自分类Dev

JQuery:所有按钮仅使用一个侦听器有任何弊端吗?

来自分类Dev

如何使用 PIL 将一个只有文本的图像添加到另一个图像上

来自分类Dev

使用来自另一个 DataFrame 的值有效地将列添加到 Pandas DataFrame

来自分类Dev

尝试使用reducer函数将一个数组中的所有值添加到JS中的另一个数组中

来自分类Dev

使用 Python 将现有 BQ 表中的列添加到另一个 BQ 表

来自分类Dev

使用 JavaScript 的事件委托设置删除事件侦听器的有效方法是什么

Related 相关文章

  1. 1

    Javascript只有最后一个事件侦听器有效

  2. 2

    将键侦听器或键绑定添加到使用ActionListener的JButton中

  3. 3

    将键添加到多个数组,并使用另一个有序数组中的相应值按顺序填充该键的值

  4. 4

    如何将事件侦听器添加到使用Jquery Event构造函数创建的Jquery Event中

  5. 5

    (Java)使用for循环获取所有组合并添加到ArrayList,但是ArrayList仅最后添加一个

  6. 6

    Onsen 2.0-使用Javascript将事件侦听器添加到Ons-Switch

  7. 7

    如何使用express和handlebar或其他模板引擎在node.js中渲染rest api调用?

  8. 8

    如何将ssl证书列表添加到使用Terraform for循环构造之一创建的alb侦听器列表中?

  9. 9

    如何使用SQLite将一个表的count()添加到具有多个其他表的联接的SQL查询中?

  10. 10

    如何使用react和typescript将事件侦听器添加到使用ref访问的div元素?

  11. 11

    在点击处理程序中使用两个useState设置器时,只有一个有效

  12. 12

    如何使用Redis将多个值添加到一个键中

  13. 13

    将事件侦听器添加到使用Javascript从API捕获的动态生成的元素中

  14. 14

    使用Lambda将侦听器添加到ObjectAnimator

  15. 15

    如何将ssl证书列表添加到使用Terraform for循环构造之一创建的alb侦听器列表中?

  16. 16

    将键侦听器或键绑定添加到使用ActionListener的JButton中

  17. 17

    将键添加到多个数组,并使用另一个有序数组中的相应值按顺序填充该键的值

  18. 18

    使用Django / South将ManyToManyField添加到现有模型中给我一个错误

  19. 19

    使用JS / JQuery按类选择文档后,将onclick事件添加到按钮

  20. 20

    这是使用侦听器的更有效方法:使用匿名类或实现列表器

  21. 21

    使用while循环创建多个按钮,但使用.onclick函数时只有第一个按钮响应

  22. 22

    与handlebar.js循环

  23. 23

    使用Underscore.js具有动态表单输入的Handlebar.js模板-Zendesk App

  24. 24

    JQuery:所有按钮仅使用一个侦听器有任何弊端吗?

  25. 25

    如何使用 PIL 将一个只有文本的图像添加到另一个图像上

  26. 26

    使用来自另一个 DataFrame 的值有效地将列添加到 Pandas DataFrame

  27. 27

    尝试使用reducer函数将一个数组中的所有值添加到JS中的另一个数组中

  28. 28

    使用 Python 将现有 BQ 表中的列添加到另一个 BQ 表

  29. 29

    使用 JavaScript 的事件委托设置删除事件侦听器的有效方法是什么

热门标签

归档