If you have a HTML element that is constantly rendered/destroyed, do the Javascript event bindings to the HTML persist, or is it necessary to bind/unbind events as part of the creation/destruction cycle?
I'm using D3 to generate a map of the counties in the US. In addition, I'm generating a tooltip overlay that includes buttons upon a click event for a valid selection.
Part of the click event handler where I bind the HTML of the template to the tooltip element and then bind the Javascript event handlers to said HTML
thisObj._tooltip.template = template : "<div id = 'tooltip_template'>" +
"<div class = 'county_data'></div>" +
"<img src = '/static/images/delete.png' width = '28' height = '28' class = 'delete_logo' id = 'close_tooltip' />" +
"<button id = 'add_prospective_market' class = 'tooltip_button'>Prospective Market</button>" +
"<button id = 'add_market' class = 'tooltip_button'>Market County</button>" +
"<button id = 'remove_market' class = 'tooltip_button'>Remove Market</button></div>"
thisObj._tooltip.tooltip.html(thisObj._tooltip.template)
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 50) + "px")
.style("pointer-events" , "auto")
.style("width", "400px")
.style("height", "150px");
$(".county_data").text(d.name + ", " + d.properties.StateCode);
addTooltipHandlers();
thisObj._tooltip.tooltip.transition()
.duration(800)
.style("opacity", 1);
I bind the event handlers to the elements via
var addTooltipHandlers = function(){
$("#add_market").on("click", function(){
console.log("Adding new Market")
});
$("#add_prospective_market").on("click", function(){
console.log("Adding new Prospective market")
});
$("#remove_market").on("click", function(){
console.log("Removing this market")
});
$("#close_tooltip")
.on("mouseover", function(){
$(this).css({"border-color" : "red", "opacity" : 1});
})
.on("mouseout", function(){
$(this).css({"border-color" : "black", "opacity" : 0.5});
})
.on("click", function(){
console.log("Closing tooltip");
d3.selectAll($("#" + thisObj._tooltip.county))
.style("fill", thisObj._currentCounty.color);
thisObj._tooltip.tooltip.transition()
.duration(500)
.style("opacity", 0)
.style("pointer-events", "none");
thisObj._tooltip.open = false;
removeTooltipHandlers();
});
}
Since a tooltip is only visible on the screen until a close event is registered, and then it is destroyed, once an event listener is bound to an element, does that binding persist when that element is destroyed and re-created?
In order for event handlers to persist you have to use event delegation in jquery
instead of
$(...).on(event, handler)
use
$(...).on(event, selector, handler)
for instance
$('body').on('click','a.saveButton', saveHandler)
This way you attach event handler to body element instead of actual element you can destroy or add to DOM. So handlers will work untill your turn them off.
Even better for all global event handlers you can use event namespaces, like:
$('body').on('click.app','a.saveButton', saveHandler)
$('body').on('click.app','a.addButton', addHandler)
This will allow you to off all of them together:
$('body').off('.app')
UPDATE: very simple jsfiddle to show event delegation.
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