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
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>
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>
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With