Связать событие только один раз
У меня есть следующий код:
function someMethod()
{
$(obj).click(function {});
}
someMethod вызывается дважды, и поэтому событие click привязывается дважды. Как я могу связать его только один раз?
Ответы
Ответ 1
Если вы можете применить его, возможно, хотите взглянуть на event.preventDefault и event.stopPropagation
ИЛИ развязывать и связывать каждый раз, в пределах вашего метода, например
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
Ответ 2
В дополнение к ответу pna вы, возможно, захотите подумать о пространстве имен вашего мероприятия, чтобы не делать случайного связывания всех событий щелчка.
function someMethod() {
$(obj).unbind('click.namespace').bind('click.namespace', function() { });
}
https://api.jquery.com/event.namespace/
Ответ 3
Нет встроенного метода, чтобы определить, связали ли вы эту конкретную функцию. Вы можете связать несколько функций щелчка с объектом. Например:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
если вы сделаете это выше, когда объект будет нажат, он будет приветствовать привет, а затем до свидания. Чтобы убедиться, что только одна функция привязана к событию клика, отвяжите обработчик события клика, затем привяжите желаемую функцию следующим образом:
$(obj).unbind('click').bind('click', function(){... });
Ответ 4
Очевидным решением является не вызов someMethod()
дважды. Если вы не можете это исправить, тогда вы можете сохранить переменную состояния, поэтому она только когда-либо связывается один раз:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Примечание: для этого используется свойство самой функции, а не введение глобальной переменной для отслеживания того, связана ли она. Вы также можете использовать свойство на самом объекте.
Вы можете увидеть, как он работает здесь: http://jsfiddle.net/jfriend00/VHkxu/.
Ответ 5
Или используйте функцию jQuery one(), которая аналогична функции on(), но только один раз запускает событие, даже если вы связываете его несколько раз.
http://api.jquery.com/one/
Ответ 6
jQuery позволяет вызвать некоторую функцию только один раз довольно легко:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
Ответ 7
Это предложение, так как я не знаю вашей логики. Может или может не работать для вас.
Попробуйте комбинировать функции jquery live() и one(), что даст вам лучший результат, чем повторная переадресация событий.
Особые случаи работают, когда у вас есть 2 элемента DOM (родительский и дочерний). Live() в родительском node гарантирует, что событие будет вызываться, а затем вызывает one() для динамического регистрации события, которое будет выполняться только один раз. (это обеспечивает аналогичную функциональность, такую как переинтерпретация).
Ответ 8
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
но я бы, вероятно, посмотрел, почему это вызвано дважды, прежде чем сделать какое-то обходное решение.
Ответ 9
Если вы хотите привязываться к объекту только один раз, вы должны реализовать флаг и придерживаться этого объекта.
Например:
if($('#id') && $('#id').data('done') == null)) {
$('#id').bind('click', function() {
alert('hello');
});
$('#id').data('done', true);
}
Ответ 10
Вы можете добавить класс css к связанным элементам, а затем отфильтровать их:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Этот метод может использоваться также для плагинов:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
Ответ 11
Вы можете использовать эту функцию расширения jQuery.
$.fn.once = function (type, fn, uid) {
if(uid == undefined) {
console.error("Called $.once without uid\n", this, "\n", fn);
}
var dataStr = type+"-handler-"+uid;
if(!this.data(dataStr)) {
this.data(dataStr, true);
this.on(type, fn);
}
};
Вместо этого
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Я делаю это
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Теперь, когда у меня есть функция вокруг нее
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
И я называю это несколько раз
addBtnHandler();
addBtnHandler();
addBtnHandler();
Он делает это только один раз.
Обратите внимание, что расширение работает, проверяя как uid, так и тип. Это означает, что вы можете связывать разные типы обработчиков с одним и тем же uid, вы можете или не захотите этого. Чтобы изменить его, отредактируйте.
var dataStr = type+"-handler-"+uid;
С чем-то вроде
var dataStr = "handler-"+uid;
Ответ 12
Я также пытался использовать метод jquery on и jQuery для привязки события только один раз с элементом dom, который еще не существует или элемент dom еще не создан.
$('.select').off('event').on('event', 'selector', function(e){ // });
Этот код не работал должным образом
Я столкнулся с очень прибыльным методом, который является "одним" методом. Это очень полезно, если вы хотите связать событие только один раз.
Здесь вы можете найти документ http://api.jquery.com/one/
Это то же самое, что и метод 'on', но отличается своим поведением, чтобы не придерживаться события для нескольких селекторов.
$('body').one('click', 'selector', function(){ // do your stuff here });
Ответ 13
Вы можете добиться этого с помощью чистого JS, используя метод addEventListener и его один раз параметр
target.addEventListener('click', handler, {once: true});