首页 > 解决方案 > addEventListener 不适用于 d3js 的 append 方法添加的元素

问题描述

我的 D3js 的 javascript 代码。我正在添加带有 id 'title' 的 div 标签。你可以在下面检查它。

const movieList = d3.select('#movielist');

movieData.forEach(function (movie) {
    movieList.append('div')
        .property('id', 'title')
        .style('width', titleWidth+'px')
        .style('height', titleHeight+'px')
        .append('p')
        .text(movie.name);
});

const title = document.getElementById('title');

title.addEventListener('click', function (e) {
    console.log(e);
})

当我这样做时,console.log(title)我可以看到title存在。但是当我使用时addEventListener没有任何反应..

标签: javascriptd3.jsaddeventlistener

解决方案


对您的问题的评论让您了解如何使代码按原样工作。但就目前而言,使用 D3 并没有多大意义。如果您希望使用 D3,让我们按预期使用 D3。D3 的核心功能围绕选择和数据绑定,您在上面没有使用,而是尝试:

const movieList = d3.select('#movielist');


const movies = movieList.selectAll(null)
   .data(movieData)
   .enter()
   .append("div")
   .style("width", titleWidth+"px")
   .style("height", titleHeight+"px")
   // d3v5 and before:
   .on("click", function(d) {
     // do something with the datum bound to each div.
   })
   // or d3v6:
   .on("click", function(event,d) {
     // do something with the datum bound to each div.
   })
   
movies.append("p")
   .text(function(d) {
      return d.name;
   })

这避免了使用循环,将数据绑定到元素(din function(d)dmovieData数组中的单个项目)。绑定的数据也传递给附加了 的子元素.append(),因此在将每部电影的名称添加到子元素时p,会写入正确的名称。

数据绑定使以后对 div 的操作更容易,因为您可以根据绑定的数据而不是 div 的属性进行操作。上面还使用 d3 来附加一个事件侦听器(对于 v3-v5 和 v6,只使用其中之一)并将该事件侦听器传递给绑定的数据。

有很多资源可以解释 selectAll().data().enter() 循环,所以我在这里不会这样做,只是说通过选择null,我们创建一个空选择,当我们将数据绑定到它时,其中的每个项目数据数组由输入选择中的一个元素表示。D3 在内部处理循环,因此缺少显式循环。

是的,你可以用普通的老式 javascript 来做这一切——也很容易;但是,该问题使用了 D3,并且此答案显示了完成手头任务的规范方法。


推荐阅读