Найкращий спосіб видалити обробник подій в jQuery?


1053

У мене є input type="image". Це діє як примітки до комірок у Microsoft Excel. Якщо хтось вводить число в текстове поле, з яким це input-imageпарно, я встановлюю обробник подій для input-image. Потім, коли користувач натискає кнопку image, вони отримують невелике спливаюче вікно, щоб додати деякі дані до даних.

Моя проблема полягає в тому, що коли користувач вводить нуль у текстове поле, мені потрібно вимкнути input-imageобробник подій. Я спробував наступне, але безрезультатно.

$('#myimage').click(function { return false; });

Відповіді:


1626

jQuery ≥ 1,7

З jQuery 1.7 і далі API подій було оновлено, .bind()/ .unbind()вони все ще доступні для зворотної сумісності, але кращим методом є використання функцій on () / off () . Нижче буде,

$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');

jQuery <1.7

У своєму прикладі коду ви просто додаєте до зображення ще одну подію клацання, не змінюючи попереднього:

$('#myimage').click(function() { return false; }); // Adds another click event

Після цього обидва події клацання будуть звільнені.

Як люди заявляли, ви можете скористатися відключенням, щоб видалити всі події натискання:

$('#myimage').unbind('click');

Якщо ви хочете додати одну подію, а потім видалити її (не видаляючи інших, які могли бути додані), тоді ви можете скористатися простором імен подій:

$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });

і видалити лише вашу подію:

$('#myimage').unbind('click.mynamespace');

6
Чи є спосіб перевірити, чи unbind()працює? Я додав це, і обидві події ще тривають.
— Девід Йелл

19
Добре, якщо обидві події все ще стартують, тоді, очевидно, це не працює. Вам потрібно буде дати більше інформації, щоб отримати правильну відповідь. Спробуйте задати окреме запитання.
— samjudson

13
Стара відповідь - так само, як включена інформація про простір імен - але я забуваю; повертає або вимикає об'єкт jQ? Якщо так, можливо, більш повною відповіддю буде ланцюжок $('#myimage').off('click').on('click',function(){...})
— ромашок

3
Так, так, так, якщо так, якщо ви хочете очистити всі інші події клацання, а потім додати свої власні, ви могли б зробити вищезазначений ланцюжок дзвінка.
— samjudson

Використання .unbind()допомогло мені в ситуації, коли я перемикав купу прапорців, але я повторно додав .click()обробник повторно, викликаючи зависання програми.
— TecBrat

63

Ця функція була недоступною, коли відповіли на це запитання, але ви також можете використовувати метод live () для вмикання / відключення подій.

$('#myimage:not(.disabled)').live('click', myclickevent);

$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });

Що станеться з цим кодом, це те, що при натисканні кнопки #mydisablebutton він додасть клас відключений до елемента #myimage. Це зробить так, що селектор більше не відповідає елементу, і подія не буде запущена, поки не буде видалено клас "інвалід", що робить селектор .live () знову дійсним.

Це має й інші переваги, додаючи також стиль на основі цього класу.


3
Хороший спосіб використання live(), ніколи не думав про використання цього способу раніше ... Окрім зручності кодування, це швидше чи він пропонує якісь інші переваги щодо використання bind / unbind?
— чакрит

2
Якщо ви додаєте / видаляєте елементи, то існують певні переваги в роботі над bind, оскільки зв'язування з live виконуваться лише один раз. jQuery, здається, рухається до більшої кількості трансляцій та делегує події, а не прив'язується до конкретних елементів.
— MacAnthony

3
Щоб вимкнути трансляцію, ви можете скористатися die ()
— Місяць

9
"Станом на jQuery 1.7, метод .live () застарілий. Використовуйте .on () для приєднання обробників подій. Користувачі старих версій jQuery повинні використовувати .delegate () у перевазі .live ()." api.jquery.com/live
— Лукас Поттерський

12
Ах, непосидючий jQuery, одного дня ти принесеш хлопцеві 300 представників, наступного дня це застаріло.
— MrBoJangles

37

Якщо ви хочете відповісти на подію лише один раз , такий синтаксис повинен бути дуже корисним:

 $('.myLink').bind('click', function() {
   //do some things

   $(this).unbind('click', arguments.callee); //unbind *just this handler*
 });

Використовуючи argument.callee , ми можемо забезпечити видалення одного конкретного обробника анонімних функцій і, таким чином, мати єдиний обробник часу для даної події. Сподіваюся, що це допомагає іншим.


2
Абсолютно, хоча іноді ви можете мати певну логіку щодо того, коли обробник повинен бути незв'язаним (наприклад, не скасовувати, якщо вони спочатку не подали текстове поле).
— ghayes

5
ARG.callee знеструмлено в суворому режимі!
— zloctb

37

Це можна зробити за допомогою функції відв’язування.

$('#myimage').unbind('click');

Ви можете додати декілька обробників подій до одного об’єкта та події в jquery. Це означає, що додавання нового не замінює старі.

Існує кілька стратегій зміни обробників подій, наприклад, простори імен подій. Про це є кілька сторінок в онлайн-документах.

Подивіться на це питання (саме так я дізнався про розв’язування). У відповідях є корисний опис цих стратегій.

Як читати зв'язані функції зворотного виклику в jquery



30

Мені довелося встановити подію на нуль за допомогою опори та attr. Я не міг зробити це з тим чи іншим. Я також не міг дістати .незалежно працювати. Я працюю над елементом TD.

.prop("onclick", null).attr("onclick", null)

1
Я проголосував за це, тому що я намагався відв'язати онблур близько 30 хвилин. '.unbind' не працювало, '.prop' не працювало, '.attr' не працювало, але ця хитрість і з .prop і .attr разом зробила трюк. дивно. Я використовую Chrome з jquery 1.7.2
— Джеремі

Те ж саме! я намагався видалити подію натискання з простого тега <a>! Дякую за це. У моєму випадку .prop ("onclick", null) було достатньо.
— Ян Лобау

те ж саме. unbind and off не працювало для мене на FF з jq 1.7.2 та .prop ("onclick", null) також було достатньо в моєму випадку
— bryanallott

4
Я думаю, причина, що вищезгадані методи не спрацювали для вас, хлопці, в тому, як ви їх налаштували. Якщо ви записали обробника подій у DOM, то так, очищення цього атрибуту необхідно, щоб очистити обробник подій, однак, я думаю, що більшість людей (включаючи мене) бажають утримувати такі речі (javascrip, обробники подій тощо) поза DOM, тому коли ми хочемо налаштувати обробник подій, ми використовуємо щось подібне, $("#elementId").click(function(){//Event execution code goes here});щоб воно взагалі не знаходилося на html-сторінці. Щоб зрозуміти, що нам насправді потрібно скористатися .unbind(), або кращим.off()
— VoidKing

Ось на кшталт того, хто щойно витратив годину, щоб виявити, що властивості, додані через jQuery, не відображаються на панелі елементів Chrome. Спробували, unbindі offце не вирішило проблему. Дуже дякую!
— Ренан

13

Якщо подія приєднана таким чином , а ціль має бути неприєднаною:

$('#container').on('click','span',function(eo){
    alert(1);

    $(this).off(); //seams easy, but does not work

    $('#container').off('click','span'); //clears click event for every span

    $(this).on("click",function(){return false;}); //this works.

});​

11

Ви можете додавати onclickобробник як вбудовану розмітку:

<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />

Якщо так, jquery .off()чи .unbind()не працюватиме. Вам також потрібно додати оригінальний обробник подій у jquery:

$("#addreport").on("click", "", function (e) {
   openAdd();
});

Тоді jquery має посилання на обробник подій і може видалити його:

$("#addreport").off("click")

VoidKing згадує про це трохи більше косо в коментарі вище.


9

Оновлено до 2014 року

Використовуючи останню версію jQuery, тепер ви можете від’єднати всі події на просторі імен, просто зробивши це $( "#foo" ).off( ".myNamespace" );



8

Для remove ВСІХ event-handlers , це те , що працює для мене:

Щоб видалити всі обробники подій, означає мати звичайну інформацію, HTML structureне event handlersприкріплену до неї elementта її child nodes. Для цього jQuery's clone()допомогли.

var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);

З цим ми маємо cloneзамість того, що originalне event-handlersмає.

Щасти...


7

Спасибі за інформацію. дуже корисно, що я використовував його для блокування взаємодії сторінки, перебуваючи в режимі редагування іншим користувачем. Я використовував його спільно з ajaxComplete. Не обов’язково однакова поведінка, але дещо схожа.

function userPageLock(){
    $("body").bind("ajaxComplete.lockpage", function(){
        $("body").unbind("ajaxComplete.lockpage");
        executePageLock();      
    });
};  

function executePageLock(){
    //do something
}

5

У випадку, якщо .on()раніше метод застосовувався з конкретним селектором, як у наступному прикладі:

$('body').on('click', '.dynamicTarget', function () {
    // Code goes here
});

І методи, unbind()і .off()методи не спрацюють.

Однак метод .undelegate () може бути використаний для повного видалення обробника з події для всіх елементів, які відповідають поточному селектору:

$("body").undelegate(".dynamicTarget", "click")

1
Я прокручував всю сторінку, шукаючи це рішення, працював як шарм.
— Абхішек Пандей

4

Якщо ви $(document).on()хочете додати слухача до динамічно створеного елемента, то, можливо, доведеться використовувати його для видалення:

// add the listener
$(document).on('click','.element',function(){
    // stuff
});

// remove the listener
$(document).off("click", ".element");


2

якщо ви встановите з onclickдопомогою htmlвам потрібноremoveAttr ($(this).removeAttr('onclick'))

якщо ви встановите його за допомогою jquery (як після першого клацання в моїх прикладах вище), тоді вам це потрібно unbind($(this).unbind('click'))


2

Я знаю, що це відбувається пізно, але чому б не використовувати звичайний JS для видалення події?

var myElement = document.getElementById("your_ID");
myElement.onclick = null;

або, якщо ви використовуєте іменовану функцію як обробник подій:

function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it

Хороша пропозиція, я вважаю за краще використовувати наявний javascript, коли такий доступний
— Michiel

1

Всі описані підходи для мене не працювали, тому що я додавав подію клацання on()в документ, де елемент був створений під час виконання:

$(document).on("click", ".button", function() {
    doSomething();
});


Моє вирішення:

Оскільки я не міг розв'язати клас ".button", я просто призначив ще один клас кнопці, яка мала ті ж стилі CSS. Роблячи це, обробник наживо / на подію остаточно проігнорував натискання:

// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");

Сподіваюся, що це допомагає.


1

Сподіваюся, мій нижче код пояснює все. HTML:

(function($){

     $("#btn_add").on("click",function(){
       $("#btn_click").on("click",added_handler);
       alert("Added new handler to button 1");
     });

  
 
     $("#btn_remove").on("click",function(){
       $("#btn_click").off("click",added_handler);
       alert("Removed new handler to button 1");
     });

  
   function fixed_handler(){
    alert("Fixed handler");
  }
  
   function added_handler(){
    alert("new handler");
  }
  
  $("#btn_click").on("click",fixed_handler);
  $("#btn_fixed").on("click",fixed_handler);
  
  
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
  <button id="btn_add">Add Handler</button>
  <button id="btn_remove">Remove Handler</button>
  <button id="btn_fixed">Fixed Handler</button>


1
чому ви переходите })(jQuery);до IIFE, коли до нього вже можна отримати доступ у глобальному масштабі?
— Брайан П

2
Добре запитання Брайан. Цей метод був введений в мій ген завдяки практиці. - Можливо, для плагіна, який не містить jquery, є змінна $, отже, я не можу безпосередньо використовувати $. - Часте використання слова "jQuery" у файлі сценарію js може збільшити розмір байта файлу, де jQuery - це 6-байтний рядок. Тому я вважаю за краще використовувати "$" або будь-яку змінну з одного байту.
— містікмо

0

Просто просто видаліть це з кнопки:

$('.classname').click(function(){
$( ".classname" ).remove();
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.