javascript - 在单击事件监听器中添加第二个单击事件监听器

标签 javascript html d3.js event-handling click

我尝试使用 D3 在现有的点击事件监听器中添加第二个点击事件监听器,但没有成功。

基本上,我有一张事件 map (圆圈)。我希望用户能够点击一个圆圈并出现一个弹出窗口。我希望该弹出窗口仅在用户第二次单击任何地方时消失。因此,单击一个圆圈将实例化弹出窗口并绑定(bind)它,第二次单击“任何地方”将使弹出窗口消失并将圆圈恢复为仅响应悬停,除非再次单击。

我通过在 circle 事件监听器中添加另一个“body”点击事件监听器来解决这个问题:

  // event listener: if events (circles) are clicked, instantiate pop-up
  d3.selectAll(".events").on("click", function(d) { 
        console.log("event clicked!")
         //disable hover event listeners
         d3.selectAll(".events").on("mouseout", null);
         d3.selectAll(".events").on("mouseover", null);              
              popup.transition()        
                 .duration(200)      
                .style("opacity", .9);
              popup.html(d.ArtistBio)

        // if user clicks a SECOND time, anywhere, make popup disappear
        d3.select("body").on("click", function(d) { 
            console.log("body clicked")
            //hide popup
            popup.transition()        
                  .duration(200)      
                  .style("opacity", 0);  
            //revert back to hover, unless user clicks again!
            d3.selectAll(".events").on("mouseout", true);
            d3.selectAll(".events").on("mouseover", true);
            d3.selectAll(".events").on("mouseout", function(d) { 
            console.log("mousing out!")      
                popup.transition()        
                  .duration(200)      
                  .style("opacity", 0);              
              })

            // mouseover event listers added back in
            d3.selectAll(".events").on("mouseover", function(d) { 
              popup.transition()        
                 .duration(200)      
                .style("opacity", .9);
              popup.html(d.ArtistBio)

          })            
        })

我的问题是这两个事件是同时触发的,而不是按顺序触发的:一旦我点击一个圆圈事件, body 点击事件监听器也被实例化,所以弹出窗口一呈现就被删除.有没有办法以类似于我上面描述的方式来做我想做的事情?提前致谢。

最佳答案

点击会冒泡,这是正常预期的。为避免这种情况,请使用 event.stopPropagation。您还可以使用 d3.events(当它们存在时...):

d3.event.stopPropagation();

这是演示,单击矩形并在其外部:

d3.select("rect").on("click", function() {
  console.log("rectangle clicked");
  d3.event.stopPropagation();
  d3.select("body").on("click", function() {
    console.log("body clicked")
  })
})
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg>
  <rect width="50" height="50" x="100" y="50"></rect>
</svg>

关于javascript - 在单击事件监听器中添加第二个单击事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58176565/

相关文章:

javascript - 了解 Gulp 管道顺序

javascript - 我应该在仅调用已经在主体中使用try and catch的函数的函数中捕获错误吗?

javascript - 如何使 HTML 正确呈现到 ExtJS 选项卡中?

javascript - 将 json 导出到 CSV 在 angularjs 中不起作用

html - 在 div 的顶部和底部添加空间

d3.js - 如何使用 nvd3 绘制对数折线图

javascript - d3 如何使圆周上的物体与中心的距离相等

javascript - 为什么 D3.js 不显示我的 geoJSON 文件?

jquery - 动态 CSS 宽度

javascript - 点未显示成线/散点组合图 d3.js