JQuery'de bir olay işleyicisini kaldırmanın en iyi yolu?


1053

Benim bir input type="image". Bu, Microsoft Excel'deki hücre notları gibi davranır. Birisi input-imagebunun eşleştirildiği metin kutusuna bir sayı girerse , için bir olay işleyicisi ayarladım input-image. Sonra kullanıcı tıkladığında image, verilere bazı notlar eklemek için küçük bir açılır pencere alır.

Benim sorunum, kullanıcı metin kutusuna sıfır girdiğinde, input-image's olay işleyicisini devre dışı bırakmak gerekir . Aşağıdaki denedim, ama boşuna.

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

Yanıtlar:


1626

jQuery ≥ 1,7

JQuery 1.7 ve sonraki sürümlerde olay API'si güncellenmiştir .bind()/ .unbind()geriye dönük uyumluluk için hala kullanılabilir, ancak tercih edilen yöntem on () / off () işlevlerini kullanmaktır. Aşağıdakiler şimdi olurdu,

$('#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

Örnek kodunuzda, öncekini geçersiz kılmak yerine görüntüye başka bir tıklama etkinliği ekliyorsunuz:

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

Her iki tıklama etkinliği de tetiklenir.

Kullanıcıların söylediği gibi, tüm tıklama etkinliklerini kaldırmak için ayırmayı kullanabilirsiniz:

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

Tek bir etkinlik eklemek ve ardından kaldırmak (eklenmiş olabilecek diğer etkinlikleri kaldırmadan) istiyorsanız, etkinlik ad boşluğunu kullanabilirsiniz:

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

ve yalnızca etkinliğinizi kaldırmak için:

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

6
Çalışıp unbind()çalışmadığını test etmenin bir yolu var mı ? Ben ekledim ve her iki olay hala devam ediyor.
David Yell

19
Her iki olay da hala ateş ediyorsa, o zaman açıkça çalışmıyor. Doğru bir cevap almak için daha fazla bilgi vermelisiniz. Ayrı bir soru sormayı deneyin.
samjudson

13
Eski cevap - dahil ad alanı bilgileri gibi - ama unutuyorum; açma / kapama jQ nesnesini döndürür? Eğer öyleyse, belki de daha eksiksiz bir cevap papatya zinciri için olacaktır:$('#myimage').off('click').on('click',function(){...})
vol7ron

3
Evet yaparlar, bu yüzden evet, diğer tüm tıklama etkinliklerini temizlemek ve ardından kendi tıklamalarınızı eklemek isterseniz yukarıdaki zincirleme çağrıyı yapabilirsiniz.
samjudson

Kullanmak .unbind()bir sürü onay kutusu arasında geçiş yaptığım bir durumda bana yardımcı oldu, ancak serbest bırakıldı, .click()işleyiciyi tekrar tekrar ekleyerek uygulamanın asılmasına neden oldu.
14'te TecBrat

63

Bu soru cevaplandığında bu kullanılamadı, ancak etkinlikleri etkinleştirmek / devre dışı bırakmak için live () yöntemini de kullanabilirsiniz .

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

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

Bu kodla ne olacak, # mydisabledüğmesine tıkladığınızda #myimage öğesine devre dışı bırakılan sınıfı ekleyecektir. Bu, seçicinin artık öğeyle eşleşmemesini ve .live () seçicisini yeniden geçerli kılmak için 'devre dışı' sınıfı kaldırılıncaya kadar etkinliğin tetiklenmemesini sağlar.

Bunun, bu sınıfa dayalı stil ekleyerek başka faydaları da vardır.


3
live()Kullanmanın güzel yolu , daha önce bu şekilde kullanmayı düşünmemiştim ... Kodlama kolaylığının yanı sıra, daha hızlı mı yoksa bağlama / çözme kullanmanın başka avantajları var mı?
chakrit

2
Eleman ekliyor / çıkarıyorsanız, canlıya bağlanma sadece bir kez yapıldığından, bağlamaya göre kesin performans avantajları vardır. jQuery belirli öğelere bağlanmak yerine daha canlı ve temsilci etkinliklere geçiyor gibi görünüyor.
MacAnthony

3
Canlı devre dışı bırakmak için die ()
Moons

9
"JQuery 1.7'den itibaren .live () yöntemi kullanımdan kaldırıldı. Olay işleyicileri eklemek için .on () kullanın. JQuery'nin eski sürümlerinin kullanıcıları .live () yerine tercihen .delegate () kullanmalıdır." api.jquery.com/live
Lucas Pottersky

12
Ah, kararsız jQuery, bir gün birisine 300 rep getir, ertesi gün modası geçmiş.
MrBoJangles

37

Bir etkinliğe yalnızca bir kez yanıt vermek istiyorsanız , aşağıdaki sözdizimi gerçekten yardımcı olacaktır:

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

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

Kullanılması arguments.callee , biz belirli bir anonim fonksiyonlu işleyicisi kaldırıldığından emin olmak ve böylece, belirli bir olay için tek bir saat işleyicisi olabilir. Umarım bu başkalarına yardımcı olur.


2
Kesinlikle, ancak bazen, işleyicinin ne zaman bağlı olmaması gerektiğiyle ilgili belirli bir mantığa sahip olmak isteyebilirsiniz (örneğin, önce bir metin kutusu vermedikçe bağlantıyı kesmeyin).
ghayes

5
arguments.callee katı modda yoksun bırakıldı!
zloctb

37

Bu, unbind fonksiyonu kullanılarak yapılabilir.

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

Jquery'de aynı nesneye ve olaya birden fazla olay işleyicisi ekleyebilirsiniz. Bu yeni bir tane eklemek eskilerinin yerini almaz demektir.

Olay işleyicilerini değiştirmek için olay ad alanları gibi çeşitli stratejiler vardır. Çevrimiçi dokümanlarda bununla ilgili bazı sayfalar var.

Şu soruya bakın (bağlamayı nasıl öğrendim). Cevaplarda bu stratejilerin bazı yararlı açıklamaları vardır.

Jquery bağlı hover geri arama işlevleri nasıl okunur


32

belki çözme yöntemi sizin için çalışacaktır

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

30

Ben pervane ve attr kullanarak null olay ayarlamak zorunda kaldı. Biri ya da diğeri ile yapamadım. Ayrıca .unbind çalışmak için alamadım. Bir TD elemanı üzerinde çalışıyorum.

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

1
Buna oy verdim çünkü yaklaşık 30 dakika boyunca bir onbur'u ayırmaya çalışıyorum. '.unbind' işe yaramadı, '.prop' işe yaramadı, '.attr' işe yaramadı, ancak .prop ve .attr ile birlikte bu hile birlikte hile yaptı. Garip. Chrome'u jquery 1.7.2 ile kullanıyorum
Jeremy

Burada aynı! Basit <a> etiketinden tıklama olayını kaldırmaya çalıştım! Bunun için teşekkürler. Benim durumumda .prop ("onclick", null) yeterliydi.
Jan Lobau

burada aynı. unbind and off benim için jq 1.7.2 ve .prop ("onclick", null) ile FF üzerinde işe yaramadı
bryanallott

4
Yukarıdaki yöntemlerin sizin için işe yaramadığının sebebi, bunu nasıl ayarladığınızdan kaynaklanıyor. Olay işleyicisini DOM'a yazdıysanız, evet, olay işleyiciyi temizlemek için bu özelliği temizlemek gerekir, ancak, çoğu insanın (ben dahil) bu tür şeyleri (javascripti, olay işleyicileri vb.) DOM, bu nedenle bir olay işleyicisi ayarlamak istediğimizde $("#elementId").click(function(){//Event execution code goes here});, html sayfasında olmaması için benzer bir şey kullanırız . Aslında kullanmamız gerektiğini .unbind()veya tercih ettiğimizi temizlemek için.off()
VoidKing 17:13

Aşağıda, jQuery aracılığıyla eklenen mülklerin Chrome'un öğe panelinde gösterilmediğini keşfetmek için bir saat ayıran birine benzer. Deniyorum unbindve offve bu sorunu çözmek değildi. Çok teşekkür ederim!
Renan

13

Olay bu şekilde eklenirse ve hedef eklenmemişse:

$('#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İşleyiciyi satır içi işaretleme olarak ekliyor olabilirsiniz :

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

Eğer öyleyse, jquery .off()ya .unbind()da çalışmaz. Orijinal olay işleyiciyi jquery'ye de eklemeniz gerekir:

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

Sonra jquery olay işleyicisi için bir başvuru var ve kaldırabilirsiniz:

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

VoidKing, yukarıdaki yorumda bundan biraz daha eğik olarak bahsediyor.


9

2014 için güncellendi

JQuery'nin en son sürümünü kullanarak artık bir ad alanındaki tüm olayları basitçe yaparak $( "#foo" ).off( ".myNamespace" );


8

Satır içi onclick etkinliğini kaldırmanın en iyi yolu $(element).prop('onclick', null);


8

To remove ALL event-handlers , bu benim için çalıştı budur:

İşleyicileri sade olması anlamına tüm olayı kaldırmak için HTML structuretüm olmadan event handlersbağlanmış elementve onun child nodes. Bunu yapmak için jQuery's clone()yardımcı oldu.

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

Bununla, üzerinde hayır olmadan cloneyerine sahip olacağız .originalevent-handlers

İyi şanslar...


7

Bilgi için teşekkürler. çok yararlı i başka bir kullanıcı tarafından düzenleme modunda iken sayfa etkileşimi kilitlemek için kullanılır. Ben ajaxComplete ile birlikte kullandım. Aslında aynı davranış değil, biraz benzer.

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

function executePageLock(){
    //do something
}

5

Halinde .on()yöntem daha önce, aşağıdaki örnekte olduğu gibi, özellikle de seçici kullanıldı:

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

Hem unbind()ve .off()yöntemler değildir işe gidiş.

Ancak .undelegate () yöntemi, geçerli seçiciyle eşleşen tüm öğelerin işleyiciyi olaydan tamamen kaldırmak için kullanılabilir:

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

1
Bu çözümü ararken sayfanın tamamını kaydırdım, bir cazibe gibi çalıştı.
Abhishek Pandey

4

Eğer kullanırsanız $(document).on()dinamik olarak oluşturulan bir elemana bir dinleyici eklemek sonra onu kaldırmak için aşağıdaki kullanmak gerekebilir:

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

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


2

onclickyoluyla ayarladıysanız htmlyapmanız gerekenremoveAttr ($(this).removeAttr('onclick'))

jquery ile ayarladıysanız (yukarıdaki örneklerimdeki ilk tıklamadan sonra olduğu gibi) unbind($(this).unbind('click'))


2

Bu geç geliyor biliyorum, ama neden olayı kaldırmak için düz JS kullanmıyorsunuz?

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

veya olay işleyici olarak adlandırılmış bir işlev kullanırsanız:

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

İyi bir öneri, mevcut olduğunda yerel javascript kullanmayı tercih ediyorum
Michiel

1

on()Öğenin çalışma zamanında oluşturulduğu belgeye click olayını eklediğim için açıklanan tüm yaklaşımlar benim için çalışmadı :

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


Geçici çözümüm:

".Button" sınıfını açamadığım için, aynı CSS stillerine sahip düğmeye başka bir sınıf atadım. Bunu yaparak canlı / olay-işleyicisi tıklamayı nihayet yok saydı:

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

Umarım yardımcı olur.


1

Umarım aşağıdaki kodum hepsini açıklar. 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);küresel olarak erişilebildiğinde neden IIFE'ye geçiyorsunuz?
Bryan P

2
Güzel soru Bryan. Bu yöntem, uygulama nedeniyle genime girildi. - Jquery olmayan eklentinin $ değişkenine sahip olması için bazı olasılıklar olabilir, bu yüzden doğrudan $ kullanamam. - Bir js komut dosyasında "jQuery" sözcüğünün sık kullanılması dosyanın bayt boyutunu artırabilir, burada jQuery 6 baytlık bir dizedir. Bu nedenle "$" veya herhangi bir tek bayt değişkeni kullanmayı tercih ederim.
mysticmo

0

Sadece düğmeden kaldırın:

$('.classname').click(function(){
$( ".classname" ).remove();
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.