Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript event binding persistence

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?

like image 685
Jason Avatar asked Feb 27 '26 20:02

Jason


1 Answers

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.

like image 124
vittore Avatar answered Mar 01 '26 11:03

vittore



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!