Связать событие только один раз

У меня есть следующий код:

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