Постоянство привязки событий 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, чтобы показать делегирование события.