на jQuery.нажмите кнопку вызывается несколько раз

Я получаю неожиданные результаты с помощью jQuery, пытаясь установить метод "click"div. Пожалуйста, смотрите этот jsfiddle. Обязательно откройте окно консоли. Щелкните слово несколько раз и посмотрите вывод консоли. Функция click вызывается несколько раз, когда она должна вызываться только один раз.

закомментированный код в конце работает просто отлично. Я делаю что-то не так? Я новичок в jQuery.

здесь код:

function toggleDiv(status)
{
    console.log("toggleDiv(" + status + ")");
    if (status) {
        $("#test").html("Goodbye");
    }
    else  {
        $("#test").html("Hello");
    }
    $("#test").click(function() {
        toggleDiv(!status);
    });

    // Non-jquery method works fine....
    //document.getElementById("test").onclick = function () {
    //    toggleDiv(!status);
    //}
}​

Update: похоже, есть много способов снять кожу с этой кошки. Реальной проблемой здесь было мое непонимание того, что функции jQuery" click " добавляют другой обработчик. Я думал, он заменил текущего обработчика.

8 ответов


вы устанавливаете новый .click() eventHandler каждый раз, когда вы продолжаете нажимать на него (что, в свою очередь, создает еще больше событий). На боковой ноте, старайтесь никогда не использовать onclick / onmouseover / onmouseout / etc события на элементах DOM. В Internet explorer они создают блоки сценариев (которые можно увидеть, если вы используете Visual Studio. Страницы с тысячами этих замедляют производительность чрезвычайно!

похоже, вы пытаетесь достичь этого:

jsFiddle Демо

$("#test").on('click', function() {
    var this$   = $(this),
        _status = !!this$.data('status'); // force to boolean
                  // ^will default to false since we have no data-status attribute yet

    this$.html(_status ? 'Hello' : 'Goodbye')
         .data('status', !_status);
});​

ты перерегистрации click обработчик снова и снова рекурсивно.

одно правильное решение (из многих возможных вариантов) это:

$(function() {
    var status = false;

    $('#test').click(function() {
        status = !status;
        $(this).html(status ? 'Goodbye' : 'Hello');
    });
});

и затем вам нужно удалить onclick атрибут из HTML - нехорошо смешивать обработку событий DOM0 и DOM3.

см.http://jsfiddle.net/alnitak/8aBxp/


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

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

function toggleDiv(status)
{
    console.log("toggleDiv(" + status + ")");
    if (status) {
        $("#test").html("Goodbye");
    }
    else  {
        $("#test").html("Hello");
    }

    $("#test").unbind();

    $("#test").click(function() {
        toggleDiv(!status);
    });
}​

вы также можете посмотреть на .тумблер() обработчик события.

обновление: чтобы быть яснее о .toggle() будет также делайте, что хотите:

$("#test").toggle(
    function(event) { $(event.target).html("Goodbye"); },
    function(event) { $(event.target).html("Hello"); }
);

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


вы должны связать click событие за пределами


после вашего if вы добавляете еще одно событие click в #test. Он вызовет все обработчики щелчков, когда он щелкнет. Вероятно, вам это вообще не нужно, так как onclick определяется в html.


наилучшим решением будет: http://jsfiddle.net/kannix/fkMf9/4/

 $("#test").click(function() {
     $(this).text(($(this).text() == "Hello") ? "Goodbye" : "Hello");
 });

та же проблема происходит со мной . Ответ Джозефа Эриксона о unbind () работает. Если это поможет, вот краткое описание того, как событие onclick было вызвано несколько раз в моем коде:

  • вызов AJAX обновляет тело таблицы. Содержимое tbody полностью динамично.
  • строки таблицы извлекаются пакетно (через улавливание на стороне сервера).
  • определенные табличные данные (td)имели гиперссылку, с которой связано событие click.(щелчок событие добавлено как часть функции обратного вызова AJAX)
  • Теперь каждый раз, когда вызывается AJAX, одно событие click связывается с td.
  • следовательно, столько раз вызывается AJAX, что многие обработчики щелчков подключаются к td.

Я решил это в соответствии с предложением Джозефа Эриксона. В обратном вызове AJAX я делаю это сейчас : $(".msgLinkDiv").развязывать(); (".msgLinkDiv").нажмите (функция (e){do my stuff});