How to externally trigger d3 events

2020-07-08 07:06发布

I have a d3 selection upon which I have defined event callbacks.

var obj = d3.select("#kk").on("mouseleave",function(){
              console.log("mouse leave");       
          });

How can I trigger the event externally? Is there something like:

obj.mouseleave(); // actuall mouse leave function calling

If there is, and if I select the object without referring to obj, will the trigger still work?

As in:

var newObje=d3.select("#kk");
newObje.mouseleave(); //will this trigger the previously defined instructions

4条回答
Evening l夕情丶
2楼-- · 2020-07-08 07:50

Yes, you don't need d3 to trigger the event, vanilla javascript is enough for that. You simply need to use the dispatchEvent function.

Here is an example of how you would do it (from a button for example).

I added both the d3.select way and the plain JS way, both should work fine.

d3.select("#kk").on("mouseleave",function(){
  console.log("mouseleave");
});

var button = document.getElementById('trigger-event');
button.onclick = function() {
  var evt = new MouseEvent("mouseleave");
  
  // The way to dispatch the event using d3
  d3.select('#kk').node().dispatchEvent(evt);
  
  // The way to dispatch it with plain JS
  document.getElementById('kk').dispatchEvent(evt);
};
#kk {
  width:100px;
  height:100px;
  background-color:blue;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="kk">
  
</div>


<button id="trigger-event">trigger event</button>

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2020-07-08 07:55

The following will trigger the mouseleave event on the elements via dispatchEvent().

  var event = document.createEvent('Event');
  event.initEvent('mouseleave', true, true);

  d3.selectAll("circle").node().dispatchEvent(event);

Example: http://codepen.io/anon/pen/eBYvVN (I've added a button at the bottom to trigger it. The mouseleave event is attached to the circles)

查看更多
再贱就再见
4楼-- · 2020-07-08 07:55

You can make one constant function for mouseleave and call it on mouse leave or externally as well like this :

function mouseleave(){            // Main mouse leave function.
     console.log('inside mouseleave function.');    
}



var obj = d3.select("#kk").on("mouseleave",function(){ // It will call on actual mouse leave event
                  console.log("mouseleave");
                  mouseleave();
              });

    mouseleave(); // call it externally when ever you want.
查看更多
家丑人穷心不美
5楼-- · 2020-07-08 08:01

If you are already on D3 v4, you can use selection.dispatch() which was specifically designed to do exactly what you are looking for:

# selection.dispatch(type[, parameters]) <>

Dispatches a custom event of the specified type to each selected element, in order.

This was included in v4 as a result of the issue "Ability to trigger event handlers manually. #100".

Furthermore, the method will enable you to dispatch events of the same type to all elements contained in the selection. The implementation of that method looks similar to the approach the other answerers took by putting event.dispatch() to use, but will make your life somewhat easier. The following snippet has a listener for each individual circle, which may all be triggered by the button at once.

var circles = d3.select("svg").selectAll("circle")
  .data(d3.range(5))
  .enter().append("circle")
    .attr("cx", function(d, i) { return 60 * i + 20; })
    .attr("cy", "30")
    .attr("r", "20").attr("fill", "blue")
    .on("mouseleave",function(){
      d3.select(this)
        .attr("fill", "red")
        .transition().duration(1000)
        .attr("fill", "blue");
    });

d3.select("#btn")
  .on("click", function() {
    circles.dispatch("mouseleave");
  });
<script src="https://d3js.org/d3.v4.js"></script>
<svg width="400" height="70"></svg>

<button id="btn">Dispatch mouseleave to all circles</button>

查看更多
登录 后发表回答