在单击事件侦听器中添加第二个单击事件侦听器

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


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


我通过在圆事件侦听器中添加另一个“主体”点击事件侦听器来解决这个问题:


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


          })            

        })

我的问题是这两个事件同时被触发,而不是按顺序触发:一旦我点击一个圆事件,主体点击事件侦听器也被实例化,因此弹出窗口在呈现后立即被删除。有没有办法以类似于我上面描述的方式做我正在尝试做的事情?提前致谢。


慕勒3428872
浏览 117回答 2
2回答

忽然笑

点击会冒泡,这是正常的预期。为避免这种情况,请使用event.stopPropagation. 您还可以使用d3.events(当它们存在时...):d3.event.stopPropagation();这是演示,单击矩形及其外部:d3.select("rect").on("click", function() {&nbsp; console.log("rectangle clicked");&nbsp; d3.event.stopPropagation();&nbsp; d3.select("body").on("click", function() {&nbsp; &nbsp; console.log("body clicked")&nbsp; })})<script src="https://d3js.org/d3.v5.min.js"></script><svg>&nbsp; <rect width="50" height="50" x="100" y="50"></rect></svg>

潇湘沐

你可以这样做:&nbsp; // event listener: if events (circles) are clicked, instantiate pop-up&nbsp; d3.selectAll(".events").on("click", function(d) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; console.log("event clicked!")&nbsp; &nbsp; &nbsp; &nbsp; const currentCircle = this;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; //disable hover event listeners&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;d3.selectAll(".events").on("mouseout", null);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;d3.selectAll(".events").on("mouseover", null);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.transition()&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.duration(200)&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .style("opacity", .9);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.html(d.ArtistBio)&nbsp; &nbsp; &nbsp; &nbsp; // if user clicks a SECOND time, anywhere, make popup disappear&nbsp; &nbsp; &nbsp; &nbsp; d3.select("body").on("click", function(d) {&nbsp;&nbsp; &nbsp; if(this !== currentCircle){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log("body clicked")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //hide popup&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.transition()&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .duration(200)&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .style("opacity", 0);&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //revert back to hover, unless user clicks again!&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d3.selectAll(".events").on("mouseout", true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d3.selectAll(".events").on("mouseover", true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d3.selectAll(".events").on("mouseout", function(d) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log("mousing out!")&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.transition()&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .duration(200)&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .style("opacity", 0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // mouseover event listers added back in&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d3.selectAll(".events").on("mouseover", function(d) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.transition()&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.duration(200)&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .style("opacity", .9);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.html(d.ArtistBio)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; })在 body 事件侦听器中,检查单击的元素是否与单击的当前圆/弹出窗口不同。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript