JQuery'deki özel etkinlikler?


180

Özel olay işleme jquery en iyi şekilde nasıl uygulanacağı hakkında bazı girdi arıyorum. 'Click' vb gibi dom öğelerinden olayları bağlamak nasıl biliyorum, ama bazı önizleme işlevselliğini işlemek için küçük bir javascript kitaplığı / eklentisi inşa ediyorum.

Ben bir dizi kural ve veri / kullanıcı girişi bir dom öğesinde bazı metni güncellemek için çalışan bir komut dosyası var, ama şimdi bu komut dosyası muhtemelen bilmiyor diğer öğelerde gösterilen aynı metne ihtiyacım var. Ne gerek bir şekilde gerekli metni üreten bu komut dosyası gözlemlemek için iyi bir kalıptır.

Peki bunu nasıl yaparım? Kullanıcı olaylarını yükseltmek / işlemek için jquery'deki bazı yerleşik işlevleri gözden kaçırdım mı yoksa bunu yapmak için bazı jquery eklentisine ihtiyacım var mı? Bunun üstesinden gelmenin en iyi yolu / eklentisi nedir?


3
Bu soruya bakan biri buna ihtiyaç duyarsa, eski sorunumu gerçekten çözebilecek başka bir çerçeve, knockoutjs.com var.
Per Hornshøj-Schierbeck

2
Bu sorudan itibar kazanmaya devam ettiğimi gören insanlar hala okuyor olmalı. Sadece mevcut müşteri tarafı mvc çerçeve seçimimi güncellemek istiyorum: angularjs.org
Per Hornshøj-Schierbeck

O açısal v1 tamamen farklı olmasına rağmen, Angular2 ( angular.io ) göstermek çok vaadi böylece ve beta / rc kaçırmış kez benim ilk seçim olacaktır.
Per Hornshøj-Schierbeck

Yanıtlar:


105

Şuna bir bak:

(süresi dolan blog sayfasından http://web.archive.org/web adresindeki arşivlenen sürüme göre http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ yeniden basılmıştır. /20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ )


JQuery ile Yayınlama / Abone Olma

17 Haziran 2008

Google Gears'ın çevrimdışı işlevselliği ile entegre edilmiş bir jQuery kullanıcı arayüzü yazmak için jQuery kullanarak ağ bağlantısı durumunu belirlemek üzere bazı kodlarla oynuyorum.

Ağ Algılama Nesnesi

Temel dayanak çok basit. Bir URL'yi düzenli aralıklarla yoklayacak bir ağ algılama nesnesi örneği oluştururuz. Bu HTTP istekleri başarısız olursa, ağ bağlantısının kesildiğini veya sunucuya şu anda erişilemediğini varsayabiliriz.

$.networkDetection = function(url,interval){
    var url = url;
    var interval = interval;
    online = false;
    this.StartPolling = function(){
        this.StopPolling();
        this.timer = setInterval(poll, interval);
    };
    this.StopPolling = function(){
        clearInterval(this.timer);
    };
    this.setPollInterval= function(i) {
        interval = i;
    };
    this.getOnlineStatus = function(){
        return online;
    };
    function poll() {
        $.ajax({
            type: "POST",
            url: url,
            dataType: "text",
            error: function(){
                online = false;
                $(document).trigger('status.networkDetection',[false]);
            },
            success: function(){
                online = true;
                $(document).trigger('status.networkDetection',[true]);
            }
        });
    };
};

Demoyu buradan izleyebilirsiniz. Tarayıcınızı çevrimdışı çalışacak şekilde ayarlayın ve neler olduğunu görün…. hayır, çok heyecan verici değil.

Tetikleyici ve Bağlama

Yine de heyecan verici olan (veya en azından beni heyecanlandıran şey), durumun uygulama aracılığıyla aktarılma yöntemidir. Ben jQuery tetik ve bağlama yöntemlerini kullanarak bir pub / alt sistemi uygulamak için büyük ölçüde tartışılmamış bir yöntem tökezledi.

Demo kodu olması gerekenden daha geniş. Ağ algılama nesnesi, 'durum' olaylarını belgede etkin bir şekilde dinleyen ve sonuç olarak olayları tüm abonelere 'bildir' yayınlar (daha sonra olanlar için). Bunun ardında yatan neden, gerçek bir dünya uygulamasında 'bildirme' olaylarının ne zaman ve nasıl yayınlanacağını kontrol etmek için muhtemelen daha fazla mantık olacağıdır.

$(document).bind("status.networkDetection", function(e, status){
    // subscribers can be namespaced with multiple classes
    subscribers = $('.subscriber.networkDetection');
    // publish notify.networkDetection even to subscribers
    subscribers.trigger("notify.networkDetection", [status])
    /*
    other logic based on network connectivity could go here
    use google gears offline storage etc
    maybe trigger some other events
    */
});

JQuery'nin DOM merkezli yaklaşım nedeniyle olaylar DOM öğelerine (tetiklenir) yayınlanır. Bu, genel olaylar için pencere veya belge nesnesi olabilir veya bir seçici kullanarak bir jQuery nesnesi oluşturabilirsiniz. Demoyu benimsediğim yaklaşım, aboneleri tanımlamak için neredeyse isimlendirilmiş bir yaklaşım yaratmak.

Abone olacak DOM öğeleri basitçe “abone” ve “ağAyarı” ile sınıflandırılır. Daha sonra, bir bildirim etkinliğini tetikleyerek etkinlikleri yalnızca bu öğelere (demoda yalnızca bir tane var) yayınlayabiliriz$(“.subscriber.networkDetection”)

#notifierBir parçası olan div .subscriber.networkDetectionabone grubuna daha sonra etkili bir dinleyici olarak hareket ederek, kendisine bağlı bir anonim işlevi vardır.

$('#notifier').bind("notify.networkDetection",function(e, online){
    // the following simply demonstrates
    notifier = $(this);
    if(online){
        if (!notifier.hasClass("online")){
            $(this)
                .addClass("online")
                .removeClass("offline")
                .text("ONLINE");
        }
    }else{
        if (!notifier.hasClass("offline")){
            $(this)
                .addClass("offline")
                .removeClass("online")
                .text("OFFLINE");
        }
    };
});

Al işte ozaman, buyur. Her şey çok ayrıntılı ve benim örneğim hiç de heyecan verici değil. Ayrıca, bu yöntemlerle yapabileceğiniz ilginç bir şey sergilemez, ancak kaynakta kazmak isteyen herkes çekinmeyin. Tüm kod demo sayfasının başında satır içi


Ne aradığını. Muhtemelen gitmenin yolu doğru, ama jquery'nin daha doğrudan ele almak için doğrudan desteğe veya bir eklentiye ihtiyaç duyduğunu düşünemiyorum. Biraz bekleyeceğim ve bir yanıtı işaretlemeden önce problemin başka
hallerini alıp almadığınızı göreceğim

6
Bu bir yerden bir teklif mi? Öyleyse, lütfen kaynağınızı belirtin ve hala varsa bir bağlantı sağlayın.
Aryeh Leib Taurog

1
Evet, teklif, düzenleme geçmişinde bu bağlantı , şu anda erişilemiyor. Arşivlenmiş sayfa burada .
Stano

1
Ben Alman minik (minik minik minik) bir jQuery pub alt eklentisi yazdı . Son derece zarif.
Barney

127

Kabul edilen cevapta verilen bağlantı , jQuery kullanarak pub / alt sistemi uygulamak için güzel bir yol gösterir , ancak kodu okumak biraz zor buldum, bu yüzden kodun basitleştirilmiş sürümü:

http://jsfiddle.net/tFw89/5/

$(document).on('testEvent', function(e, eventInfo) { 
  subscribers = $('.subscribers-testEvent');
  subscribers.trigger('testEventHandler', [eventInfo]);
});

$('#myButton').on('click', function() {
  $(document).trigger('testEvent', [1011]);
});

$('#notifier1').on('testEventHandler', function(e, eventInfo) { 
  alert('(notifier1)The value of eventInfo is: ' + eventInfo);
});

$('#notifier2').on('testEventHandler', function(e, eventInfo) { 
  alert('(notifier2)The value of eventInfo is: ' + eventInfo);
});

10
Bu cevabı gerçekten çok beğendim. Herkes, trigger () bind () (ve on ()) üzerindeki dokümanları okuyabilir, ancak bu cevap jquery kullanarak bir olay veri yolu (pub / alt sistemi) oluşturmanın somut bir örneğini sunar.
lostdorje

1
Bravo. Bilmem gereken her şey.
Patrick Fisher

Özel bir olayı tetiklediğinizde bir dizi (nerede uzunluk> 1) geçirirseniz, dinleyicinin bağımsız değişkenlerindeki tüm dizi öğelerini alacağını, böylece nbağımsız değişkenlerin sayısıyla sonuçlanacağını buldum.
vsync

dinleyicide ele alınan çoklu argümanlara çözüm:var eventData = [].slice.call(arguments).splice(1)
vsync

2
#Notifier kukla öğeleri olmadan bunu yapmanın bir yolu var mı? Bir javascript kütüphanem vardı ve bir nesnenin bir olayı açığa çıkarmasını isteseydim, sayfada hangi öğelerin bulunduğundan emin olamıyorum.
AaronLS

21

Sanırım .. gibi özel olayları 'bağlamak' mümkündür ( http://docs.jquery.com/Events/bind#typedatafn ):

 $("p").bind("myCustomEvent", function(e, myName, myValue){
      $(this).text(myName + ", hi there!");
      $("span").stop().css("opacity", 1)
               .text("myName = " + myName)
               .fadeIn(30).fadeOut(1000);
    });
    $("button").click(function () {
      $("p").trigger("myCustomEvent", [ "John" ]);
    });

1
Bir etkinlik oluşturmanın ve abonelerin / dinleyicilerin bunu tetiklemesinin bir yolunu arıyorum.
Yükselen

2
Bu kod bunu yapıyor, değil mi? myCustomEventyükseltildiğinde, üstteki bağ bir dinleyici ekler.
Sprintstar

15

Benzer bir sorum vardı, ama aslında farklı bir cevap arıyordum; Özel bir etkinlik oluşturmak istiyorum. Örneğin, her zaman bunu söylemek yerine:

$('#myInput').keydown(function(ev) {
    if (ev.which == 13) {
        ev.preventDefault();
        // Do some stuff that handles the enter key
    }
});

Bunu kısaltmak istiyorum:

$('#myInput').enterKey(function() {
    // Do some stuff that handles the enter key
});

tetikleme ve bağlama tüm hikayeyi anlatmaz - bu bir JQuery eklentisidir. http://docs.jquery.com/Plugins/Authoring

"EnterKey" işlevi jQuery.fn'ye özellik olarak eklenir - bu gerekli koddur:

(function($){
    $('body').on('keydown', 'input', function(ev) {
        if (ev.which == 13) {
            var enterEv = $.extend({}, ev, { type: 'enterKey' });
            return $(ev.target).trigger(enterEv);
        }
    });

    $.fn.enterKey = function(selector, data, fn) {
        return this.on('enterKey', selector, data, fn);
    };
})(jQuery);

http://jsfiddle.net/b9chris/CkvuJ/4/

Yukarıdakilerin bir özelliği, klavye girişlerini aşağıdaki gibi bağlantı dinleyicilerinde zarif bir şekilde işleyebilmenizdir:

$('a.button').on('click enterKey', function(ev) {
    ev.preventDefault();
    ...
});

Düzenlemeler: Doğru thisiçeriği işleyiciye düzgün bir şekilde iletmek ve herhangi bir dönüş değerini işleyiciden jQuery'ye geri döndürmek için güncellendi (örneğin, olayı ve köpürmeyi iptal etmek istiyorsanız). Anahtar kodu ve olayı iptal etme yeteneği de dahil olmak üzere, işleyicilere uygun bir jQuery olay nesnesini geçirecek şekilde güncellendi.

Eski jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/


Chris - fonksiyon mükemmel çalıştı .. thats çalışmıyor bu şey erişiyor tek şey .. i. E.currentTarget kullanarak erişebilirsiniz .. ama daha verimli bir yolu olup olmadığını merak ediyordum.
Addy

Bu böcek iyi yakalandı. Evet, satır 5'i işleyiciden (ev) değiştirirseniz; kime: handler.call (bu, ev); bu argüman normalde standart jquery olay işleyicilerinde olduğu gibi olacaktır. jsfiddle.net/b9chris/VwEb9
Chris

Bunu başka bir şekilde uygulamanın bir yolunu da biliyor musunuz? Ben bu örneği kullanmaya çalışıyorum ama scrollhangi ile yayılmaz. Dinleyicilerin vücuda sabit onkodlaması yerine, olayı kendileri ateşlemek için onlara bağlı olan unsurlara ihtiyacım olduğunu düşünüyorum.
Gust van de Wal

Sorduğunuz senaryodan emin değilim; en iyi kod örneği ile bir Soru olarak sorulabilir?
Chris Moschini

9

Eski bir gönderi, ancak yeni bir bilgi ile güncellemeye çalışacağım.

Özel etkinlikleri kullanmak için, onu bir DOM öğesine bağlamanız ve tetiklemeniz gerekir. Yani kullanmalısın

.on () yöntemi, bir olay türünü ve bir olay işleme işlevini bağımsız değişken olarak alır. İsteğe bağlı olarak, olayla ilgili verileri üçüncü bağımsız değişkene iterek olayla ilgili verileri ikinci bağımsız değişkeni olarak da alabilir. Aktarılan tüm veriler, olay nesnesinin data özelliğindeki olay işleme işlevi tarafından kullanılabilir. Olay işleme işlevi her zaman olay nesnesini ilk bağımsız değişkeni olarak alır.

ve

.trigger () yöntemi, bağımsız değişken olarak bir olay türünü alır. İsteğe bağlı olarak, bir dizi değer de alabilir. Bu değerler, olay nesnesinden sonra bağımsız değişkenler olarak olay işleme işlevine iletilir.

Kod şöyle görünür:

$(document).on("getMsg", {
    msg: "Hello to everyone",
    time: new Date()
}, function(e, param) {
    console.log( e.data.msg );
    console.log( e.data.time );
    console.log( param );
});

$( document ).trigger("getMsg", [ "Hello guys"] );

Burada ve burada güzel bir açıklama bulunabilir . Bu tam olarak neden faydalı olabilir? Twitter mühendisinin bu mükemmel açıklamasında nasıl kullanılacağını buldum .

PS Düz javascript'te bunu yeni CustomEvent ile yapabilirsiniz , ancak IE ve Safari sorunlarına dikkat edin.


3

Özel etkinlikleri şu şekilde yazarım:

var event = jQuery.Event('customEventName');
$(element).trigger(event);

Verilmiş, sadece yapabilirsin

$(element).trigger('eventname');

Ancak yazdığım yol, kullanıcının varsayılanı engelleyip engellemediğini tespit etmenizi sağlar

var prevented = event.isDefaultPrevented();

Bu, formunuzdaki bir düğme öğesini tıklatırsanız ancak bir hata varsa formun gönderilmesini istemiyorsanız gibi son kullanıcının belirli bir olayı işlemeyi durdurma isteğini dinlemenize olanak tanır.


Sonra genellikle böyle olayları dinlerim

$(element).off('eventname.namespace').on('eventname.namespace', function () {
    ...
});

Bir kez daha yapabilirsin

$(element).on('eventname', function () {
    ...
});

Ama bunu her zaman biraz güvensiz buldum, özellikle de bir ekipte çalışıyorsanız.

Aşağıdakilerle ilgili yanlış bir şey yoktur:

$(element).on('eventname', function () {});

Ancak, herhangi bir nedenden dolayı bu olayı kaldırmam gerektiğini varsayalım (devre dışı bırakılmış bir düğme hayal edin). O zaman yapmam gerekecekti

$(element).off('eventname', function () {});

Bu işlemden tüm eventnameetkinlikler kaldırılacak $(element). Gelecekte bir kişinin bir etkinliği de o öğeye bağlayıp bağlamayacağını bilemezsiniz ve o etkinliği yanlışlıkla da kaldırırsınız

Bundan kaçınmanın güvenli yolu, etkinliklerinizi adlandırarak

$(element).on('eventname.namespace', function () {});

Son olarak, ilk satırın

$(element).off('eventname.namespace').on('eventname.namespace', ...)

Ben aynı olay işleyicisinin asla birden fazla kez çağrılmadığından emin olmak için bağlamadan önce kişisel olarak her zaman bir etkinliği çözerim (bunun bir ödeme formundaki gönder düğmesi olduğunu ve etkinliğin 5 kez bağlandığını hayal edin)


hoş bir yaklaşım. Ad alanı için +1.
Aurovrata
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.