JQuery में कस्टम इवेंट?


180

मैं सबसे अच्छा तरीका jquery में कस्टम ईवेंटहैंडलिंग को लागू करने के तरीके के बारे में कुछ इनपुट की तलाश कर रहा हूं। मुझे पता है कि 'क्लिक' आदि जैसे प्रमुख तत्वों से घटनाओं को कैसे हुक किया जाए, लेकिन मैं कुछ पूर्वावलोकन कार्यक्षमता को संभालने के लिए एक छोटी जावास्क्रिप्ट लाइब्रेरी / प्लगइन का निर्माण कर रहा हूं।

मुझे नियमों और डेटा / उपयोगकर्ता इनपुट के एक सेट से डोम तत्व में कुछ पाठ को अद्यतन करने के लिए एक स्क्रिप्ट चल रही है, लेकिन अब मुझे अन्य तत्वों में दिखाए गए उसी पाठ की आवश्यकता है जो इस स्क्रिप्ट को संभवतः पता नहीं चल सकता है। किसी भी आवश्यक पाठ का निर्माण करने वाली इस लिपि का अवलोकन करने के लिए मुझे एक अच्छे पैटर्न की आवश्यकता है।

फिर मेरे द्वारा इसे कैसे किया जाएगा? क्या मैंने उपयोगकर्ता घटनाओं को बढ़ाने / संभालने के लिए jquery में कुछ अंतर्निहित कार्यक्षमता को अनदेखा किया है या क्या मुझे इसे करने के लिए कुछ jquery प्लगइन की आवश्यकता है? आपको क्या लगता है इसे संभालने का सबसे अच्छा तरीका / प्लगइन है?


3
एक और ढांचा है, knockoutjs.com जो वास्तव में मेरी पुरानी समस्या को हल कर सकता है, अगर इस प्रश्न को देखने वाले को इसकी आवश्यकता है।
प्रति हॉर्नशोज-शियरबेक

2
यह देखकर कि मुझे इस सवाल से प्रतिष्ठा मिलती रहती है, लोगों को अभी भी इसे पढ़ना चाहिए। मैं सिर्फ क्लाइंट साइड mvc ढांचे की अपनी वर्तमान पसंद को अद्यतन करना चाहता हूं: angularjs.org
प्रति हॉर्नशो-शियरबेक

भले ही यह कोणीय v1 से पूरी तरह से अलग है, Angular2 ( angular.io ) इतना वादा दिखाता है और बीटा / आरसी से बाहर होने के बाद मेरा पहला पिक होगा।
प्रति हॉर्नशोज-शियरबेक

जवाबों:


105

इस पर एक नजर डालिए:

(समय सीमा समाप्त ब्लॉग पेज से पुनर्प्रकाशित http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ पर संग्रहीत संस्करण के आधार पर http://web.archive.org/web /20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ )


JQuery के साथ प्रकाशित / सदस्यता लें

17 जून, 2008

Google Gears की ऑफ़लाइन कार्यक्षमता के साथ एकीकृत jQuery UI लिखने की दृष्टि से, मैं jQuery का उपयोग करके नेटवर्क कनेक्शन की स्थिति के लिए कुछ कोड के साथ मतदान कर रहा हूं।

नेटवर्क डिटेक्शन ऑब्जेक्ट

मूल आधार बहुत सरल है। हम एक नेटवर्क डिटेक्शन ऑब्जेक्ट का एक उदाहरण बनाते हैं जो नियमित अंतराल पर एक URL को प्रदूषित करेगा। क्या इन HTTP अनुरोधों को विफल होना चाहिए, हम यह मान सकते हैं कि नेटवर्क कनेक्टिविटी खो गई है, या वर्तमान समय में सर्वर अप्राप्य है।

$.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]);
            }
        });
    };
};

आप यहां डेमो देख सकते हैं। ऑफ़लाइन काम करने के लिए अपना ब्राउज़र सेट करें और देखें कि क्या होता है…। नहीं, यह बहुत रोमांचक नहीं है।

ट्रिगर और बिंद

हालांकि रोमांचक क्या है (या कम से कम मुझे क्या रोमांचक है) वह विधि है जिसके द्वारा स्थिति एप्लिकेशन के माध्यम से रिले हो जाती है। मैं jQuery के ट्रिगर और बाइंड विधियों का उपयोग करते हुए एक पब / उप प्रणाली को लागू करने की एक काफी हद तक बिना चर्चा की पद्धति पर ठोकर खाई है।

डेमो कोड होना चाहिए की तुलना में अधिक obtuse है। नेटवर्क डिटेक्शन ऑब्जेक्ट document स्टेटस ’ईवेंट्स को उस डॉक्यूमेंट को प्रकाशित करता है जो सक्रिय रूप से उनके लिए सुनता है और बदले में सभी सब्सक्राइबरों को 'नोटिफाई’ ईवेंट्स प्रकाशित करता है (बाद में उन पर)। इसके पीछे तर्क यह है कि एक वास्तविक विश्व अनुप्रयोग में 'सूचित' घटनाओं को प्रकाशित और कब प्रकाशित किया जाता है, इसे नियंत्रित करने में शायद कुछ और तर्क होंगे।

$(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 के DOM सेंट्रिक एप्रोच ईवेंट्स को DOM एलिमेंट्स (ट्रिगर पर) में प्रकाशित किया जाता है। यह सामान्य घटनाओं के लिए विंडो या दस्तावेज़ ऑब्जेक्ट हो सकता है या आप एक चयनकर्ता का उपयोग करके एक jQuery ऑब्जेक्ट उत्पन्न कर सकते हैं। डेमो के साथ मैंने जो दृष्टिकोण लिया है, वह ग्राहकों को परिभाषित करने के लिए लगभग नामांकित दृष्टिकोण बनाना है।

DOM तत्व जो सब्सक्राइबर होने हैं, उन्हें केवल "सब्सक्राइबर" और "networkDetection" के साथ वर्गीकृत किया गया है। हम तब केवल इन तत्वों (जिनमें से डेमो में केवल एक है) पर घटनाओं को प्रकाशित कर सकते हैं, जिससे एक सूचित घटना शुरू हो सकती है$(“.subscriber.networkDetection”)

#notifierDiv जो का हिस्सा है .subscriber.networkDetectionग्राहकों की समूह तो एक गुमनाम समारोह में यह करने के लिए बाध्य, प्रभावी रूप से एक श्रोता के रूप में अभिनय किया है।

$('#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");
        }
    };
});

तो यह तूम गए वहाँ। यह सब बहुत अच्छा है और मेरा उदाहरण बिल्कुल रोमांचक नहीं है। यह भी दिलचस्प नहीं है कि आप इन विधियों के साथ क्या कर सकते हैं, लेकिन अगर किसी को भी स्रोत के माध्यम से खुदाई करने में दिलचस्पी है, तो वह कुछ भी नहीं दिखा सकता है। सभी कोड डेमो पेज के प्रमुख में इनलाइन है


मैं क्या देख रहा था। वह शायद सही है कि यह जाने का रास्ता है, लेकिन मैं यह सोचने में मदद नहीं कर सकता कि अधिक सुंदर तरीके से इसे संभालने के लिए jquery को प्रत्यक्ष समर्थन या एक प्लगइन की आवश्यकता है। मैं थोड़ा इंतजार करूँगा और देखूंगा कि क्या कोई समस्या है, इससे पहले कि मैं एक जवाब दूं झंडा :)
हॉर्नशो-शियरबेक

6
क्या यह कहीं से एक उद्धरण है? यदि ऐसा है, तो कृपया अपने स्रोत का हवाला दें, और एक लिंक प्रदान करें, अगर यह अभी भी मौजूद है।
Aryeh Leib Taurog

1
हाँ, यह उद्धरण है, संपादित इतिहास में यह लिंक है , वर्तमान में यह दुर्गम है। संग्रहित पृष्ठ यहाँ है
स्टेनो

1
बेन अल्मन ने एक नन्हा (नन्हा नन्हा नन्हा) jQuery पब सब प्लगइन लिखा । यह बेहद खूबसूरत है।
बार्नी

127

स्वीकृत उत्तर में प्रदान किया गया लिंक jQuery का उपयोग करके पब / सब सिस्टम को लागू करने का एक अच्छा तरीका दिखाता है , लेकिन मुझे कोड पढ़ने में कुछ मुश्किल लगा, इसलिए यहां कोड का मेरा सरलीकृत संस्करण है:

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
मुझे वास्तव में यह उत्तर पसंद है। डॉक्स ट्रिगर () बाइंड () (और ऑन ()) पर पढ़ सकते हैं, लेकिन यह उत्तर jquery का उपयोग करके एक इवेंट बस (पब / सब सिस्टम) बनाने का एक ठोस उदाहरण प्रदान करता है।
लॉडॉरजे

1
वाहवाही। मुझे जो कुछ भी जानना चाहिए था।
पैट्रिक फिशर

मैंने पाया है कि यदि आप एक सरणी (जहाँ लंबाई> 1) पास करते हैं, जब आप एक कस्टम घटना को ट्रिगर करते हैं, तो श्रोता को सभी तर्कों में सभी तर्क आइटम मिलेंगे, इसलिए आप nतर्कों की संख्या के साथ समाप्त हो जाएंगे ।
vsync

श्रोता को संभालने वाले कई तर्कों का समाधान:var eventData = [].slice.call(arguments).splice(1)
vsync

2
वहाँ #notifier डमी तत्वों के बिना यह करने के लिए एक रास्ता है? अगर मेरे पास एक जावास्क्रिप्ट लाइब्रेरी थी और किसी घटना को उजागर करने के लिए एक वस्तु चाहिए थी, तो मुझे यकीन नहीं हो सकता कि पृष्ठ पर क्या तत्व मौजूद हैं।
एरोनल्स

21

मुझे ऐसा लगता है .. यह संभव है कि कस्टम घटनाओं को 'बाइंड' किया जा सके, जैसे ( 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
मैं एक घटना को बढ़ाने और उस पर ग्राहकों / श्रोताओं को ट्रिगर करने का एक तरीका ढूंढ रहा हूं। इसे मैन्युअल रूप से ट्रिगर न करें क्योंकि
उठाई गई

2
यह कोड ऐसा करता है, है ना? myCustomEventउठाया जाता है, शीर्ष पर बाँध एक श्रोता जोड़ता है।
स्प्रिंटस्टार

15

मेरे पास एक समान प्रश्न था, लेकिन वास्तव में एक अलग उत्तर की तलाश में था; मैं एक कस्टम ईवेंट बनाना चाह रहा हूँ। उदाहरण के लिए हमेशा यह कहने के बजाय:

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

मैं इसे संक्षिप्त करना चाहता हूं:

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

ट्रिगर और बाइंड पूरी कहानी नहीं बताती है - यह एक JQuery प्लगइन है। http://docs.jquery.com/Plugins/Authoring

"EnterKey" फ़ंक्शन jQuery.fn के लिए एक संपत्ति के रूप में संलग्न हो जाता है - यह आवश्यक कोड है:

(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/

उपरोक्त की एक अच्छी बात यह है कि आप लिंक श्रोताओं पर कृपापूर्वक कीबोर्ड इनपुट को संभाल सकते हैं जैसे:

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

संपादन: ठीक thisसे हैंडलर को सही संदर्भ देने के लिए अद्यतन किया गया है , और हैंडलर से jQuery में किसी भी वापसी मान को वापस करने के लिए (उदाहरण के लिए यदि आप घटना और बुदबुदाहट को रद्द करने के लिए देख रहे थे)। हैंडलर के लिए एक उचित jQuery ईवेंट ऑब्जेक्ट को पास करने के लिए अपडेट किया गया, जिसमें कुंजी कोड और ईवेंट को रद्द करने की क्षमता शामिल है।

पुराना jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/


क्रिस - फ़ंक्शन ने पूरी तरह से काम किया .. केवल एक चीज जो काम नहीं कर रही है वह इस चर को एक्सेस कर रही है .. मैं इसे e.currentTarget का उपयोग करके एक्सेस करने में सक्षम हूं .. लेकिन सोच रहा था कि क्या अधिक कुशल तरीका है।
Addy

उस बग पर अच्छी पकड़। हां, यदि आप हैंडलर (ईवी) से लाइन 5 बदलते हैं; को: handler.call (यह, ev); फिर यह तर्क वैसा ही होगा जैसा कि सामान्य तौर पर मानक jquery ईवेंट हैंडलर में होता है। jsfiddle.net/b9chris/VwEb9
क्रिस मोसिनची

क्या आप इसे दूसरे तरीके से लागू करने के तरीके के बारे में भी जानते हैं? मैं इस उदाहरण का उपयोग करने की कोशिश कर रहा हूं scroll, लेकिन इसके साथ , जो प्रचार नहीं करता है। मुझे लगता है कि श्रोताओं को शरीर के लिए onकठोर होने के बजाय, मुझे उन तत्वों की आवश्यकता है जो स्वयं को घटना को आग लगाने के लिए बाध्य करते हैं।
Gust van de Wal

गस्ट मैं आपके द्वारा पूछे जा रहे परिदृश्य के बारे में अनिश्चित हूं; कोड नमूने के साथ एक प्रश्न के रूप में सबसे अच्छा पूछा जा सकता है?
क्रिस मोसची

9

यह एक पुरानी पोस्ट है, लेकिन मैं इसे एक नई जानकारी के साथ अपडेट करने की कोशिश करूंगा।

कस्टम घटनाओं का उपयोग करने के लिए आपको इसे कुछ DOM तत्व से बांधने और इसे ट्रिगर करने की आवश्यकता है। इसलिए आपको उपयोग करने की आवश्यकता है

.on () विधि एक घटना प्रकार और एक इवेंट हैंडलिंग फ़ंक्शन को तर्क के रूप में लेती है। वैकल्पिक रूप से, यह ईवेंट-संबंधित डेटा को इसके दूसरे तर्क के रूप में भी प्राप्त कर सकता है, जो ईवेंट हैंडलिंग फ़ंक्शन को तीसरे तर्क पर धकेलता है। जो भी डेटा पास किया जाता है वह इवेंट ऑब्जेक्ट के डेटा प्रॉपर्टी में ईवेंट हैंडलिंग फ़ंक्शन के लिए उपलब्ध होगा। ईवेंट हैंडलिंग फ़ंक्शन हमेशा इवेंट ऑब्जेक्ट को उसके पहले तर्क के रूप में प्राप्त करता है।

तथा

.trigger () विधि अपने तर्क के रूप में एक घटना प्रकार लेती है। वैकल्पिक रूप से, यह एक मान भी ले सकता है। ये मान ईवेंट हैंडलिंग फ़ंक्शन को इवेंट ऑब्जेक्ट के बाद तर्क के रूप में दिए जाएंगे।

कोड इस तरह दिखता है:

$(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"] );

अच्छी व्याख्या यहाँ और यहाँ मिल सकती है । क्यों वास्तव में यह उपयोगी हो सकता है? मैंने पाया कि ट्विटर इंजीनियर से इस उत्कृष्ट स्पष्टीकरण में इसका उपयोग कैसे करें ।

PS सादे जावास्क्रिप्ट में आप इसे नए CustomEvent के साथ कर सकते हैं , लेकिन IE और Safari समस्याओं से सावधान रहें।


3

यहां बताया गया है कि मैं किस तरह से कस्टम ईवेंट्स लिखता हूं:

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

दी, आप बस कर सकते हैं

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

लेकिन जिस तरह से मैंने लिखा है वह आपको यह पता लगाने की अनुमति देता है कि उपयोगकर्ता ने डिफ़ॉल्ट रूप से रोका है या नहीं

var prevented = event.isDefaultPrevented();

यह आपको किसी विशेष ईवेंट को संसाधित करने से रोकने के लिए अपने अंतिम-उपयोगकर्ता के अनुरोध को सुनने की अनुमति देता है, जैसे कि यदि आप एक फार्म में एक बटन तत्व पर क्लिक करते हैं, लेकिन त्रुटि होने पर पोस्ट करने के लिए फ़ॉर्म को नहीं करना चाहते हैं।


मैं तो आमतौर पर इस तरह की घटनाओं को सुनता हूं

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

एक बार फिर, आप बस कर सकते हैं

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

लेकिन मैंने हमेशा इसे कुछ हद तक असुरक्षित पाया है, खासकर यदि आप एक टीम में काम कर रहे हैं।

निम्नलिखित में कुछ भी गलत नहीं है:

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

हालांकि, मान लें कि मुझे इस घटना को जो भी कारण (एक अक्षम बटन की कल्पना करें) को अनबाइंड करने की आवश्यकता है। मुझे तब करना होगा

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

यह सब दूर कर देगा eventname घटनाओं$(element) । आप यह नहीं जान सकते कि क्या भविष्य में कोई व्यक्ति उस तत्व के लिए एक घटना भी बाँध सकता है, और आप अनजाने में उस घटना को भी अनसुना कर देंगे

इससे बचने का सुरक्षित तरीका है कि आप अपनी घटनाओं का नामकरण करें

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

अंत में, आपने देखा होगा कि पहली पंक्ति थी

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

मैं व्यक्तिगत रूप से हमेशा एक घटना को केवल एक बंधन में बांधने से पहले सुनिश्चित करता हूं कि एक ही ईवेंट हैंडलर को कई बार कॉल न किया जाए (कल्पना करें कि यह भुगतान फ़ॉर्म पर सबमिट बटन था और ईवेंट 5 बार बाउंड किया गया था)


अच्छा दृष्टिकोण। नाम स्थान के लिए +1।
अरोवरता
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.