Как проверить, связано ли событие click - JQuery

Я связываю событие click с кнопкой:

$('#myButton').bind('click',  onButtonClicked);

В одном сценарии это вызвано несколько раз, поэтому, когда я делаю trigger, я вижу несколько вызовов ajax, которые я хочу предотвратить.

Как я bind, только если он не связан раньше.

Ответ 1

Обновление 24 Авг '12. В jQuery 1.8 больше невозможно получить доступ к событиям элемента с помощью .data('events'). (Подробнее см. эту ошибку.) Доступ к тем же данным можно получить с помощью jQuery._data(elem, 'events'), внутренней структуры данных, которая недокументирована и, следовательно, а не 100% гарантированно останутся стабильными. Однако это не должно быть проблемой, и соответствующая строка кода плагина выше может быть изменена на следующее:

var data = jQuery._data(this[0], 'events')[type];

События jQuery хранятся в объекте данных с именем events, поэтому вы можете искать в нем:

var button = $('#myButton');
if (-1 !== $.inArray(onButtonClicked, button.data('events').click)) {
    button.click(onButtonClicked);
}

Было бы лучше, конечно, если бы вы могли структурировать ваше приложение, поэтому этот код только вызывается один раз.


Это может быть инкапсулировано в плагин:

$.fn.isBound = function(type, fn) {
    var data = this.data('events')[type];

    if (data === undefined || data.length === 0) {
        return false;
    }

    return (-1 !== $.inArray(fn, data));
};

Затем вы можете позвонить:

var button = $('#myButton');
if (!button.isBound('click', onButtonClicked)) {
    button.click(onButtonClicked);
}

Ответ 2

Еще один способ - отметить такие кнопки с помощью класса CSS и фильтра:

$('#myButton:not(.bound)').addClass('bound').bind('click',  onButtonClicked);

В последних версиях jQuery замените bind на on:

$('#myButton:not(.bound)').addClass('bound').on('click',  onButtonClicked);

Ответ 3

Если используется jQuery 1.7 +:

Вы можете вызвать off до on:

$('#myButton').off('click', onButtonClicked) // remove handler
              .on('click', onButtonClicked); // add handler

Если нет:

Вы можете просто отменить первое событие:

$('#myButton').unbind('click', onButtonClicked) //remove handler
              .bind('click', onButtonClicked);  //add handler

Ответ 4

Лучший способ, который я вижу, - использовать live() или delegate() для захвата события в родительском, а не в каждом дочернем элементе.

Если ваша кнопка находится внутри элемента #parent, вы можете заменить:

$('#myButton').bind('click', onButtonClicked);

по

$('#parent').delegate('#myButton', 'click', onButtonClicked);

даже если #myButton еще не существует, когда этот код выполняется.

Ответ 5

Я написал очень маленький плагин под названием "один раз", который делает это. Выполнить и включить элемент.

$.fn.once = function(a, b) {
    return this.each(function() {
        $(this).off(a).on(a,b);
    });
};

И просто:

$(element).once('click', function(){
});

Ответ 6

Здесь моя версия:

Utils.eventBoundToFunction = function (element, eventType, fCallback) {
    if (!element || !element.data('events') || !element.data('events')[eventType] || !fCallback) {
        return false;
    }

    for (runner in element.data('events')[eventType]) {
        if (element.data('events')[eventType][runner].handler == fCallback) {
            return true;
        }

    }

    return false;
};

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

Utils.eventBoundToFunction(okButton, 'click', handleOkButtonFunction)

Ответ 7

На основании ответа @konrad-garus, но используя data, так как я полагаю, что class должен использоваться в основном для стилизации.

if (!el.data("bound")) {
  el.data("bound", true);
  el.on("event", function(e) { ... });
}

Ответ 8

Почему бы не использовать этот

unbind() до bind()

$('#myButton').unbind().bind('click',  onButtonClicked);

Ответ 9

Чтобы избежать проверки/привязки/отмены привязки, вы можете изменить свой подход! Почему вы не используете Jquery.on()?

Поскольку Jquery 1.7,.live(),.delegate() устарел, теперь вы можете использовать .on() для

Присоедините обработчик событий для всех элементов, которые соответствуют текущему селектору, сейчас и в будущем

Это означает, что вы можете прикрепить событие к родительскому элементу, который все еще существует, и присоединить дочерние элементы, независимо от того, присутствуют они или нет!

Когда вы используете .on() вот так:

$('#Parent').on('click', '#myButton'  onButtonClicked);

Вы ловите событие click на parent и оно ищет дочерний '#myButton', если существует...

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

Ответ 10

Пытаться:

if (typeof($("#myButton").click) != "function") 
{
   $("#myButton").click(onButtonClicked);
}

Ответ 11

if ($("#btn").data('events') != undefined && $("#btn").data('events').click != undefined) {
    //do nothing as the click event is already there
} else {
    $("#btn").click(function (e) {
        alert('test');
    });
}

Ответ 12

По состоянию на июнь 2019 года я обновил функцию (и она работает для того, что мне нужно)

$.fn.isBound = function (type) {
    var data = $._data($(this)[0], 'events');

    if (data[type] === undefined || data.length === 0) {
        return false;
    }
    return true;
};

Ответ 13

JQuery имеет решение:

$( "#foo" ).one( "click", function() {
  alert( "This will be displayed only once." );
}); 

эквивалентны:

$( "#foo" ).on( "click", function( event ) {
  alert( "This will be displayed only once." );
  $( this ).off( event );
});