在点击事件监听器中添加第二点击事件监听器

问题描述 投票:1回答:2

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

[基本上,我有一个事件图(圆圈)。我希望用户可以单击一个圆圈并显示一个弹出窗口。我希望该弹出窗口仅在用户第二次单击任何地方时消失。因此,单击一个圆将实例化弹出窗口并将其绑定,然后再次单击“任何地方”将使弹出窗口消失并还原圆,使其仅响应于悬停,除非再次单击一个圆。

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

  // 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)

          })            
        })

我的问题是事件同时被触发,而不是顺序触发:一旦我单击一个循环事件,主体单击事件侦听器也会被实例化,因此弹出窗口一被渲染就被删除。有没有一种方法可以按照我上面描述的方式来做我想做的事情?预先感谢。

javascript html d3.js event-handling click
2个回答
0
投票

您可以执行以下操作:

  // event listener: if events (circles) are clicked, instantiate pop-up
  d3.selectAll(".events").on("click", function(d) { 
        console.log("event clicked!")
        const currentCircle = this; 
        //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) { 
    if(this !== currentCircle){
            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)

          })
       }            
        })

在主体事件监听器中,检查单击的元素是否与单击的当前圆/弹出窗口不同。


0
投票

点击会冒出气泡,这是正常预期的。为避免这种情况,请使用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>
© www.soinside.com 2019 - 2024. All rights reserved.