Постоянство привязки событий Javascript

Если у вас есть элемент HTML, который постоянно визуализируется / уничтожается, сохраняются ли привязки событий javascript к HTML, или необходимо связывать / отменять привязку событий как часть цикла создания / уничтожения?

Я использую D3 для создания карты округов в США. Кроме того, я создаю наложение всплывающей подсказки, которое включает кнопки для события щелчка для правильного выбора.

Часть обработчика события click, где я связываю HTML шаблона с элементом подсказки, а затем связываю обработчики событий javascript с указанным 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);

Я связываю обработчики событий с элементами через

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();
   });
}

Поскольку всплывающая подсказка отображается на экране только до тех пор, пока не будет зарегистрировано событие закрытия, а затем оно будет уничтожено, когда прослушиватель событий привязан к элементу, сохраняется ли эта привязка, когда этот элемент уничтожается и создается заново?

1 ответ

Решение

Чтобы обработчики событий сохранялись, вы должны использовать делегирование событий в jquery.

вместо

$(...).on(event, handler)

использование

$(...).on(event, selector, handler)

например

$('body').on('click','a.saveButton', saveHandler)

Таким образом, вы присоединяете обработчик события к элементу body вместо фактического элемента, который вы можете уничтожить или добавить в DOM. Так что обработчики будут работать до тех пор, пока вы их не выключите.

Еще лучше для всех глобальных обработчиков событий вы можете использовать пространства имен событий, например:

$('body').on('click.app','a.saveButton', saveHandler)
$('body').on('click.app','a.addButton', addHandler)

Это позволит вам off все вместе

$('body').off('.app')

ОБНОВЛЕНИЕ: очень простой jsfiddle, чтобы показать делегирование события.

Другие вопросы по тегам