Как заменить обработчик событий на jQuery? - PullRequest
3 голосов
/ 31 августа 2010

У меня есть сайт, который использует AJAX для навигации.У меня есть две страницы, на которых я использую функцию щелчка и перетаскивания, используя

$(".myDragArea").mousedown(function(){
  do stuff...
  mouseDrag = true; // mouseDrag is global.
});

$("body").mousemove(function(){
  if (mouseDrag) {
    do stuff...
  }
});

$("body").mouseup(function(){
  if (mouseDrag) {
    do stuff...
    mouseDrag = false;
  }
});

Я просто набираю это, поэтому извините за любые случайные синтаксические ошибки.В двух частях сайта используется практически идентичный код, с той лишь разницей, что внутри функции $("body").mouseup().Однако, если я получу доступ к первой части, а затем перейду ко второй части, код, который запускается при наведении мыши, не изменится.Я прошел по коду с помощью firebug, и при запуске $("body").mouseup() при загрузке второй части никаких ошибок или ошибок не было.

Итак, почему не изменяется обработчик событий, когда я запускаю $("body").mouseup() во второй раз?

Ответы [ 3 ]

11 голосов
/ 31 августа 2010

Использование $("body").mouseup( ... ) добавит обработчик событий для тела, которое запускается при mouseup.

Если вы хотите добавить другой обработчик событий, который будет конфликтовать с текущим обработчиком (ями) событий, то вы должны сначала удалить текущий обработчик (ы) конфликтующих событий.

У вас есть 4 варианта сделать это с .unbind () . Я перечислю их от наименее точных до самых точных вариантов:

  1. Nuclear option - Удалить все обработчики событий из body

    $("body").unbind();
    

    Это довольно грубо. Попробуем улучшить.

  2. The elephant gun - Удалить все mouseup обработчики событий из body

    $("body").unbind('mouseup');
    

    Это немного лучше, но мы можем быть еще точнее.

  3. The surgeon's scalpel - Удалить один конкретный обработчик событий из body

    $("body").unbind('mouseup', myMouseUpV1);    
    

    Конечно, для этой версии вы должны установить переменную для вашего обработчика событий. В вашем случае это будет выглядеть примерно так:

    myMouseUpV1 = function(){
      if (mouseDrag) {
        do stuff...
        mouseDrag = false;
      }
    }
    
    $("body").mouseup(myMouseUpV1);
    
    $("body").unbind('mouseup', myMouseUpV1);
    $("body").mouseup(myMouseUpV2); // where you've defined V2 somewhere
    
  4. Scalpel with anesthesia (хорошо, аналогия изнашивается) - вы можете создавать пространства имен для обработчиков событий, которые вы связываете и отменяете Вы можете использовать эту технику для привязки и отмены привязки либо анонимных функций, либо ссылок на функции. Для пространств имен вы должны использовать метод .bind() напрямую вместо одного из ярлыков (например, .mouseover()).
    Чтобы создать пространство имен:

    $("body").bind('mouseup.mySpace', function() { ... });
    

    или

    $("body").bind('mouseup.mySpace', myHandler);
    

    Затем, чтобы отсоединить любой из предыдущих примеров, вы должны использовать:

    $("body").unbind('mouseup.mySpace');
    

    Вы можете отсоединить сразу несколько обработчиков пространства имен, связав их по цепочке:

    $("body").unbind('mouseup.mySpace1.mySpace2.yourSpace');
    

    Наконец, вы можете отменить привязку всех обработчиков событий в пространстве имен независимо от типа события!

    $("body").unbind('.mySpace')
    

    Вы не можете сделать это с простой ссылкой на обработчик. $("body").unbind(myHandler) будет не работать, так как с простой ссылкой на обработчик вы должны указать тип события ($("body").unbind('mouseup', myHandler))!


PS: Вы также можете отменить привязку события внутри себя, используя .unbind(event). Это может быть полезно, если вы хотите запускать обработчик событий только ограниченное количество раз .

var timesClicked = 0;
$('input').bind('click', function(event) {
  alert('Moar Cheezburgerz!');
  timesClicked++;
  if (timesClicked >= 2) {
    $('input').unbind(event);
    $('input').val("NO MOAR!");
  }
});​
3 голосов
/ 31 августа 2010

Вызов $("body").mouseup(function) добавит обработчик событий.
Вам нужно удалить существующий обработчик, написав $("body").unbind('mouseup');.

1 голос
/ 31 августа 2010

jQUery не «заменяет» обработчики событий при подключении обработчиков.

Если вы используете Ajax для навигации и не обновляете общий DOM (т.е. не создаете совершенно новый элемент тела длязапрос), затем выполнение новой строки, например:

$("body").mouseup(function(){

, просто добавит дополнительный обработчик .Ваш первый обработчик все еще будет существовать.

Вам нужно будет специально удалить все обработчики, вызвав

$("body").unbind("mouseUp");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...