olayı yalnızca bir kez bağla


104

Takip koduna sahibim:

function someMethod()
{
  $(obj).click(function {});
}

someMethod iki kez çağrılır ve bu nedenle click olayı iki kez bağlanır. Nasıl yalnızca bir kez bağlanmasını sağlayabilirim?


Yanıtlar:


190

Uygulayabiliyorsanız , muhtemelen event.preventDefault ve event.stopPropagation'a bir göz atmak VEYA her seferinde yönteminiz dahilinde

function someMethod()
{
  $(obj).off('click').on('click', function(e) {
    // put your logic in here 
  });
}

19
Dikkatli olun, çünkü bu TÜM tıklama olaylarının bağlantısını kaldırır ve her zaman istenen bir davranış değildir. Örneğin, bir şeyi belgeye bağladığınızda, hepsini değil, yalnızca tek bir olayı çözmek istersiniz.
Mārtiņš Briedis

26
Yanlışlıkla diğer tıklama etkinliklerinin bağlantısını kesmek istemiyorsanız, kullanmak isteyebilirsiniz function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Manu


89

Pna'nın cevabına ek olarak, kazayla tüm tıklama olaylarını çözmemek için etkinliğinizin ad aralığını belirlemeyi düşünebilirsiniz.

function someMethod () {
    $ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {});
}

https://api.jquery.com/event.namespace/


10
Kabul edilen cevap bu olmalıdır. Tüm tıklama olaylarının bağlantısının kaldırılması işleri kolayca bozabilir - özellikle de çok sayıda jQuery içeren karmaşık bir projeyse . Bunun için teşekkürler! Bu basit ad alanı çözümünü bilmiyordum !!
Simon Steinberger

Mevcut jQuery ile bu $(obj).off()ve $(obj).on()sırasıyla olmalıdır . Aksi takdirde, ad aralığı yardımcı oldu ve bu işe yaradı. Teşekkür ederim!
aexl

19

Bu belirli işlevi önceden bağlayıp bağlamadığınızı belirlemek için yerleşik bir yöntem yoktur. Bir nesneye birden çok tıklama işlevi bağlayabilirsiniz. Örneğin:

$('#id').bind('click', function(){
alert('hello');
});


$('#id').bind('click', function(){
alert('goodbuy');
});

Eğer nesne tıklandığında yukarıdakileri yaparsanız, merhaba uyarısı verir ve sonra hoşçakalın. Click olayına yalnızca bir işlevin bağlı olduğundan emin olmak için, click olay işleyicisinin bağlantısını kaldırın ve ardından istenen işlevi şu şekilde bağlayın:

$(obj).unbind('click').bind('click', function(){... });

12

Bariz çözüm, someMethod()iki kez aramamaktır. Bunu düzeltemezseniz, bir durum değişkenini tutabilirsiniz, böylece yalnızca şu şekilde bir kez bağlanır:

function someMethod()
{
    if (!someMethod.bound) {
        $(obj).click(function() {});
        someMethod.bound = true;
    }
}

Not: Bu, bağlı olup olmadığını izlemek için bir global değişken sunmak yerine işlevin kendisinin bir özelliğini kullanır. Nesnenin kendisinde de bir özellik kullanabilirsiniz.

Çalıştığını burada görebilirsiniz: http://jsfiddle.net/jfriend00/VHkxu/ .


11

Veya jQuery'nin on () işlevine benzer, ancak olayı birden çok kez bağlasanız bile yalnızca bir kez tetikleyen one () işlevini kullanın.

http://api.jquery.com/one/


8
Bazen yardımcı olur. ancak bazen şunları yapabileceğiniz çözümü istersiniz: BİR KEZ EKLE AMA BİRÇOK KULLANIM.
Rzassar

5

jQuery, bazı işlevleri çağırmayı yalnızca bir kez oldukça kolay hale getirir:

function someMethod()
{

     $(obj).click(function() {});
      this.someMethod = $.noop;
}

1
Bu yalnızca bazı Yöntemler bir nesnenin veya genel işlevin yöntemi ise işe yarar.
jcubic

jQuery.noopsadece bir karakter daha kısadır function(){}, bu yüzden burada "yardımcı" olduğunu söylemek biraz saçma, sadece boş bir işlev sağlıyor. İşte bu genel çözümün jQuery olmayan yöntem dışı bir örneği:var fn = function(){ fn = function(){}; do stuff; };
1j01

1
@ 1j01 $Bunun yerine kullanılmak üzere düzenlendi
Esailija

2

Mantığınızı bilmediğim için bu bir öneri. Sizin için çalışabilir veya çalışmayabilir.

Jquery live () ve bir () işlevini birleştirmeyi deneyin, size olay yeniden bağlantılarından daha iyi bir sonuç verecektir.

Özel durumlar, 2 DOM öğeniz (üst ve alt öğe) olduğunda çalışır. Üst düğümdeki Live (), olayın çağrılacağından emin olur ve ardından yalnızca bir kez yürütülecek olayı dinamik olarak kaydetmek için birini () çağırır. (bu, yeniden bağlama gibi benzer işlevsellik sağlar).


One()fonksiyon çalıştı chromeama işe yaramadı safariiçinde Mac.
Melez Prens

2

Bağlı öğelere css sınıfı ekleyebilir ve ardından bunları filtreleyebilirsiniz:

function someMethod()
{
    $(obj).not('.click-binded')
          .click(function {})
          .addClass('click-binded');
}

Bu yöntem, eklentiler için de kullanılabilir:

  $(obj).not('.datetimepicker-applied')
        .datetimepicker()
        .addClass('datetimepicker-applied');

1
var bound = false;

function someMethod()
{
    if(!bound)
    {
       $(obj).click(function {});
       bound = true;
    }
}

ama muhtemelen bir tür geçici çözüm yapmadan önce neden iki kez çağrıldığını araştıracağım.


3
Bu şekilde gidiyorsanız, jfriend00'ün global ad alanını kirletmek yerine nereye boundeklendiğini düşünün someMethod().
nuala

1

Nesneye yalnızca bir kez bağlanmak istiyorsanız, bir bayrak uygulamalı ve o nesneye bağlı kalmalısınız.

Örneğin:

if($('#id') && $('#id').data('done') == null)) {
    $('#id').bind('click', function() {
        alert('hello');
    });

    $('#id').data('done', true);
}

1

Bu jQuery uzantı işlevini kullanabilirsiniz.

$.fn.once = function (type, fn, uid) {
  if(uid == undefined) {
    console.error("Called $.once without uid\n", this, "\n", fn);
  }

  var dataStr = type+"-handler-"+uid;
  if(!this.data(dataStr)) {
    this.data(dataStr, true);
    this.on(type, fn);
  }
};

Bunu yapmak yerine

$("button").on("click", function(){
  alert("You Clicked On A Button");
});

Bunu yaparsın

$("button").once("click", function(){
  alert("You Clicked On A Button");
}, "btnHandler");

Şimdi etrafında bir işlevim olduğunda

function addBtnHandler() {
  $("button").once("click", function() {
    alert("You Clicked On A Button");
  }, "btnHandler");
}

Ve ben onu defalarca çağırıyorum

addBtnHandler();
addBtnHandler();
addBtnHandler();

Sadece bir kez yapar.

Uzantının hem uid hem de türü kontrol ederek çalıştığına dikkat edin. Bu, farklı türde işleyicileri aynı kullanıcı kimliği ile bağlayabileceğiniz anlamına gelir, bunu isteyebilir veya istemeyebilirsiniz. Değiştirmek için düzenleyin.

var dataStr = type+"-handler-"+uid;

Gibi bir şeyle

var dataStr = "handler-"+uid;


1

Ben de henüz var olmayan dom öğesi ile yalnızca bir kez bağlama olayı için jquery'nin off and on yöntemini kullanmaya çalışıyordum veya dom öğesi henüz oluşturulmamış.

$('.select').off('event').on('event', 'selector', function(e){ // });

Bu kod düzgün çalışmıyordu

'Tek' yöntem olan çok kazançlı bir yöntemle karşılaştım. Bir olayı yalnızca bir kez bağlamak istediğinizde çok kullanışlıdır.

Belgeyi burada bulabilirsiniz http://api.jquery.com/one/

Bu, yöntem 'açık' ile aynıdır, ancak birden çok seçici için olaya bağlı kalmama davranışıyla farklıdır.

$('body').one('click', 'selector', function(){ // do your stuff here });

1

Bunu, addEventListener yöntemini ve bir kerelik seçeneğini kullanarak saf JS ile elde edebilirsiniz.

target.addEventListener('click', handler, {once: true});

2
Bu, öğe bir kez tıklandıktan sonra olayın bağlantısının kaldırılmasına neden olur. Bu, olayların birden çok kez bağlanması sorununu çözmez.
En İyi Kedi
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.