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

将事件侦听器添加到动态创建的元素中

将事件侦听器添加到动态创建的元素中

有只小跳蛙 2021-11-18 16:06:45
我目前在尝试为foreignObject使用 vanilla JS 呈现的某些s添加单击事件侦听器时遇到一些问题。当我在点击功能上使用内置的 d3 时,它可以工作,但我更愿意使用 javascript 代码完成它。但是,该函数永远不会为这些元素触发,我不明白为什么。代码示例不完整,但应该突出显示我正在尝试做的事情。var nodes = g.selectAll("foreignObject")    .data(response.nodes)    .enter()    .append("foreignObject")    .attr("x", function(d) {        return d.x - nodeWidth / 2;    })    .attr("y", function(d) {        return d.y - nodeHeight / 2;    })    .attr("width", nodeWidth)    .attr("height", nodeHeight)    .append("xhtml:div")    .attr("class", "outer")    .html(function(d) {         var nodeHtml = createNodeElement(d);        return nodeHtml.outerHTML;    })   // If I append the img like this, it works, but ends up in the wrong "element scope"   .append("img")        .attr("class", "optionsImg")        .attr("src","/images/options-squares.svg")        .on("click", function(d) {            currentTooltipObject = d;            renderTooltipDiv();        });function createNodeElement(d) {    let nodeElement = document.createElement("div");    nodeElement.className = "nodeElement";    let nodeOptionsImg = document.createElement("img");    nodeOptionsImg.className = "nodeOptionsImg";    nodeOptionsImg.src = "/images/options-squares.svg";    nodeOptionsImg.addEventListener("click", function() {        console.log("Clicked on optionsImg for this object: "+d);    });    nodeElement.appendChild(nodeOptionsImg);    return nodeElement;}
查看完整描述

2 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

您的方法的主要问题是使用outerHTML和innerHTML(由 内部使用.html())来创建/移动/复制元素有点像序列化和反序列化您的 HTML DOM 树。这适用于 HTML 元素本身,但是,它不保留事件侦听器。因此,createNodeElement在此过程中,您附加到函数中元素的侦听器将丢失。这是其他问题的变体,例如“是否可以在不破坏后代事件侦听器的情况下附加到innerHTML?” .


如果您退后一步并重新阅读 D3 API文档,您会发现您实际上已经差不多了:D3 提供了将本机 DOM 节点附加到选择的方法:


选择。追加(类型)<>


如果指定的类型是函数,则对每个选定元素进行评估,依次传递当前数据 ( d )、当前索引 ( i ) 和当前组 ( nodes ),并将this作为当前 DOM 元素(节点[ i ])。这个函数应该返回一个要追加的元素。


如果您想坚持createNodeElement使用本机 JS 方法创建元素的实现,您可以简单地将该函数传递给,selection.append()因为它返回一个新创建的节点及其<img>子节点。因此,您的代码可以简化为:


var nodes = g.selectAll("foreignObject")

    /* styling omitted */

  .append("xhtml:div")

    .attr("class", "outer")

  .append(createNodeElement);

因为只有对 DOM 节点的引用才会被传递到所有附加到元素的事件监听器也将被保留。


查看完整回答
反对 回复 2021-11-18
?
慕斯709654

TA贡献1840条经验 获得超5个赞

createNodeElement函数中nodeOptionsImg元素尚未呈现时执行addEventListener。侦听器只能添加到渲染元素。


查看完整回答
反对 回复 2021-11-18
  • 2 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

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