কীভাবে jQuery এর সাথে আবদ্ধ ইভেন্টগুলি অর্ডার করবেন


164

আসুন বলতে দিন যে আমার কাছে একটি ওয়েব অ্যাপ্লিকেশন রয়েছে যার একটি পৃষ্ঠাতে 4 টি স্ক্রিপ্ট ব্লক থাকতে পারে - আমি যে স্ক্রিপ্টটি লিখি সেগুলি ব্লকগুলির মধ্যে একটিতে পাওয়া যেতে পারে তবে আমি জানি না যে কোনটি, এটি নিয়ামক দ্বারা পরিচালিত।

আমি কিছু onclickইভেন্টগুলিকে একটি বোতামে আবদ্ধ করি , তবে আমি দেখতে পাই যে তারা কখনও কখনও এমন কোনও ক্রমে কার্যকর করে যা আমি প্রত্যাশা করি না।

অর্ডার নিশ্চিত করার কোনও উপায় আছে, বা অতীতে আপনি কীভাবে এই সমস্যাটি পরিচালনা করেছেন?


1
একটি কলব্যাক অবজেক্টে আপনার কলব্যাকগুলি যুক্ত করুন এবং আপনি যখন তাদের গুলি চালাতে চান তখন আপনি সেগুলি একবারে ফায়ার করতে পারেন এবং সেগুলি যুক্ত ক্রমে চালিত হবে। api.jquery.com/jQuery.Callbacks
Tyddlywink

উত্তর:


28

আমি যুগে যুগে এই ধরণের প্রক্রিয়াটিকে সাধারণীকরণের জন্য চেষ্টা করে আসছিলাম, তবে আমার ক্ষেত্রে আমি কেবল শৃঙ্খলে প্রথম ইভেন্ট শ্রোতার আদেশের সাথেই উদ্বিগ্ন ছিলাম।

যদি এটির কোনও ব্যবহার হয় তবে এখানে আমার jQuery প্লাগইনটি একটি ইভেন্ট শ্রোতার সাথে জড়িত যা অন্যদের আগে সর্বদা ট্রিগার হয়:

** jQuery পরিবর্তনের সাথে আপডেট করা ইনলাইন (ধন্যবাদ তোসকান) **

(function($) {
    $.fn.bindFirst = function(/*String*/ eventType, /*[Object])*/ eventData, /*Function*/ handler) {
        var indexOfDot = eventType.indexOf(".");
        var eventNameSpace = indexOfDot > 0 ? eventType.substring(indexOfDot) : "";

        eventType = indexOfDot > 0 ? eventType.substring(0, indexOfDot) : eventType;
        handler = handler == undefined ? eventData : handler;
        eventData = typeof eventData == "function" ? {} : eventData;

        return this.each(function() {
            var $this = $(this);
            var currentAttrListener = this["on" + eventType];

            if (currentAttrListener) {
                $this.bind(eventType, function(e) {
                    return currentAttrListener(e.originalEvent); 
                });

                this["on" + eventType] = null;
            }

            $this.bind(eventType + eventNameSpace, eventData, handler);

            var allEvents = $this.data("events") || $._data($this[0], "events");
            var typeEvents = allEvents[eventType];
            var newEvent = typeEvents.pop();
            typeEvents.unshift(newEvent);
        });
    };
})(jQuery);

বিষয়গুলি নোট করুন:

  • এটি পুরোপুরি পরীক্ষা করা হয়নি।
  • এটি jQuery ফ্রেমওয়ার্কটি পরিবর্তিত হচ্ছে না (কেবলমাত্র ২.০.২.২ দিয়ে পরীক্ষা করা হয়েছে) এর অভ্যন্তরের উপর নির্ভর করে।
  • উত্স উপাদানটির অ্যাট্রিবিউট হিসাবে বা jQuery বাইন্ড () এবং অন্যান্য সম্পর্কিত ফাংশনগুলি ব্যবহার ব্যতীত অন্য কোনওভাবে আবদ্ধ হওয়া ইভেন্ট শ্রোতার আগে এটি অগত্যা ট্রিগার হবে না।

এটি লক্ষণীয় গুরুত্বপূর্ণ যে এটি কেবল jQuery এর মাধ্যমে যুক্ত ইভেন্টগুলির জন্যও কাজ করে।
গ্রিন

1
এই কোন যেহেতু এটি ব্যবহার কাজ না this.data("events"), দেখুন এখানে stackoverflow.com/questions/12214654/...
Toskan

4
আছে: একটি অনুরূপ ফাংশন যে আমাদের jQuery 1.8 এখানে আপডেট করা হয়েছে stackoverflow.com/a/2641047/850782
EpicVoyage

136

ক্রমটি যদি গুরুত্বপূর্ণ হয় তবে আপনি নিজের ইভেন্ট তৈরি করতে পারবেন এবং কলব্যাকগুলিকে আগুনে বাঁধতে পারবেন যখন এই ইভেন্টগুলি অন্যান্য কলব্যাক দ্বারা ট্রিগার করা হয়।

$('#mydiv').click(function(e) {
    // maniplate #mydiv ...
    $('#mydiv').trigger('mydiv-manipulated');
});

$('#mydiv').bind('mydiv-manipulated', function(e) {
    // do more stuff now that #mydiv has been manipulated
    return;
});

অন্তত এমন কিছু।


23
আমাদের বাইন্ড কোডের আগে কোনও সময়ে সংজ্ঞায়িত কলব্যাকগুলির জন্য ক্লিক ইভেন্টের প্রচার বন্ধ করতে চাইলে কী হয়।
ভিনিলিওস

2
আমি জিজ্ঞাসা করতে পারি কেন এটি অগ্রহণযোগ্য ছিল? বর্তমানে গৃহীত উত্তরগুলি আমার উত্তরটিকে সর্বোত্তম পদ্ধতি হিসাবে উল্লেখ করেছে, তাই আমি একধরণের বিভ্রান্ত। :-)
দোভস্কি

এটি মকোরিয়াকের ক্ষেত্রে কাজ করে, তবে একই ইভেন্টটি একাধিকবার বলা হচ্ছে না তবে। আমার অনুরূপ সমস্যা রয়েছে, যেখানে একক কীস্ট্রোক (উইন্ডো) scস্ক্রোল () একাধিকবার বিপরীত ক্রমে ট্রিগার করে ।
কেএক্সসং

37

আপনার সমস্ত কলব্যাক সবসময় উপস্থিত থাকে এবং আপনি একে অপরের উপর নির্ভরশীল হয়ে আপনি খুশি হন তবে ডাউস্কির পদ্ধতিটি ভাল।

আপনি যদি কলব্যাকগুলি একে অপরের থেকে স্বতন্ত্র থাকতে চান তবে আপনাকে বুদবুদ দেওয়ার সুবিধা নিতে হবে এবং পরবর্তী ঘটনাগুলি পিতামাতার উপাদানগুলির প্রতিনিধি হিসাবে সংযুক্ত করতে হবে। মৌলিক উপাদানগুলিতে হ্যান্ডলারগুলি নথির ঠিক অবধি অব্যাহত রেখে উপাদানটিতে হ্যান্ডলারের পরে ট্রিগার করা হবে। হ্যান্ডলারগুলি এড়িয়ে যেতে এবং অ্যাকশনটি বাতিল বা বাতিল করতে আপনি যেমন ব্যবহার করতে পারেন event.stopPropagation(), এটি বেশ ভাল event.preventDefault()

$( '#mybutton' ).click( function(e) { 
    // Do stuff first
} );

$( '#mybutton' ).click( function(e) { 
    // Do other stuff first
} );

$( document ).delegate( '#mybutton', 'click', function(e) {
    // Do stuff last
} );

অথবা, যদি আপনি এটি পছন্দ না করেন তবে আপনি কোনও ইভেন্টকে শেষের দিকে আবদ্ধ করতে বাধ্য করতে নিক লেচস বাইন্ডলাস্ট প্লাগইন ব্যবহার করতে পারেন: https://github.com/nickyleach/jQuery.bindLast

অথবা, আপনি যদি jQuery 1.5 ব্যবহার করেন তবে আপনি নতুন ডিফার্ড অবজেক্টের সাথে কিছুটা চালাকও করতে পারেন।


6
.delegateআর ব্যবহার করা হয় না এবং আপনার এখন ব্যবহার করা উচিত .on, তবুও আপনি কীভাবে একই আচরণে পৌঁছতে পারবেন তা আমি জানি নাon
eric.itzhak

: প্লাগইন যেহেতু এটি কোন এখানে দেখতে কাজ করে না সংশোধন করা হয়েছে পেতে হয়েছে stackoverflow.com/questions/12214654/...
Toskan

@ এরিক.হিটক .on () পুরানো .delegate () এর মতো আচরণ করার জন্য, কেবল এটি একটি নির্বাচকের সাথে সরবরাহ করুন। বিশদগুলি
স্যাম কফম্যান 16

আপনি সাড়া জাগানো সুবিধা গ্রহণ করতে চান আমি মনে করি ঘটনা চাহিদা হতে সরাসরি বদলে অর্পণapi.jquery.com/on/#direct-and-delegated-events
এভারেট

15

সীমাবদ্ধ কলব্যাকগুলি যে আদেশে ডাকা হয় তা প্রতিটি jQuery অবজেক্টের ইভেন্টের ডেটা দ্বারা পরিচালিত হয়। এমন কোনও ক্রিয়াকলাপ নেই (যা আমি জানি) যা আপনাকে সরাসরি সেই ডেটা দেখতে এবং পরিচালনা করার অনুমতি দেয়, আপনি কেবলমাত্র বাঁধাই () এবং আনবাইন্ড () বা সমমানের সহায়ক ফাংশনগুলির কোনওটি) ব্যবহার করতে পারেন।

ডাউস্কির পদ্ধতিটি সর্বোত্তম, "আসল" ইভেন্টের সাথে আবদ্ধ "প্রথম" কলব্যাকের সাহায্যে কাস্টম ইভেন্টগুলির ক্রমযুক্ত আদেশের সাথে আবদ্ধ হতে আপনাকে বিভিন্ন বাউন্ড কলব্যাকগুলি পরিবর্তন করতে হবে। এইভাবে, তারা যে অর্ডারে আবদ্ধ তা নির্ধারিত নয়, ক্রমটি সঠিক উপায়ে কার্যকর করা হবে।

আমি কেবলমাত্র বিকল্পটি দেখতে পাচ্ছি যা আপনি সত্যই সত্যই চিন্তা করতে চান না: যদি আপনি জানেন যে ফাংশনগুলির বাঁধাইয়ের সিনট্যাক্সটি আপনার আগে আবদ্ধ হতে পারে, তবে এই সমস্ত ফাংশন আন-বাঁধাই করার চেষ্টা করুন এবং তারপরে পুনরায় আবদ্ধ করার চেষ্টা করুন them যথাযথ ক্রমে নিজেকে। এটি কেবল সমস্যার জন্য জিজ্ঞাসা করছে, কারণ এখন আপনার নকল কোড রয়েছে।

এটি দুর্দান্ত হবে যদি jQuery আপনাকে কোনও অবজেক্টের ইভেন্টের ডেটাতে কেবল বাউন্ড ইভেন্টের ক্রম পরিবর্তন করার অনুমতি দেয় তবে jQuery কোরটিতে কিছু কোড না লিখে যা সম্ভব বলে মনে হয় না। এবং এটির অনুমতি দেওয়ার সম্ভাবনা রয়েছে যা আমি ভেবে দেখিনি, তাই সম্ভবত এটি একটি উদ্দেশ্যমূলক বাদ পড়ে ission


12
jquery ব্যবহার করে কোনও উপাদানকে আবদ্ধ সমস্ত ইভেন্টগুলি দেখতে var allEvents = $। ডেটা (এটি, "ইভেন্ট") ব্যবহার করুন;
redsquare

9

দয়া করে মনে রাখবেন যে jQuery মহাবিশ্বে এটি অবশ্যই সংস্করণ 1.8 অনুযায়ী আলাদাভাবে প্রয়োগ করা উচিত। নিম্নলিখিত প্রকাশের নোটটি jQuery ব্লগ থেকে এসেছে:

.ডাটা ("ইভেন্টগুলি"): jQuery প্রতিটি ইভেন্টের ইভেন্টগুলির নাম (এটির জন্য অপেক্ষা করুন) নামের একটি ডেটা অবজেক্টে তার ইভেন্ট সম্পর্কিত ডেটা সংরক্ষণ করে। এটি একটি অভ্যন্তরীণ ডেটা কাঠামো তাই ১.৮ এ এটি ব্যবহারকারীর ডেটা নাম স্থান থেকে সরানো হবে যাতে এটি একই নামের আইটেমগুলির সাথে বিরোধ না করে won't jQuery এর ইভেন্টের ডেটা এখনও jQuery._data (উপাদান, "ইভেন্ট") এর মাধ্যমে অ্যাক্সেস করা যায়

হ্যান্ডলারগুলি কার্যকর করার আদেশে আমাদের সম্পূর্ণ নিয়ন্ত্রণ রয়েছে jQuery মহাবিশ্বে । রিকো উপরে এটি দেখায়। দেখে মনে হচ্ছে না যে তার উত্তরটি তাকে প্রচুর ভালবাসা অর্জন করেছে, তবে এই কৌশলটি খুব কার্যকর। উদাহরণস্বরূপ, যেকোন সময় আপনার নিজের হ্যান্ডলারটি কোনও গ্রন্থাগারের উইজেটের কোনও হ্যান্ডলারের আগে সম্পাদন করতে হবে তা বিবেচনা করুন বা শর্তসাপেক্ষে আপনার উইজেটের হ্যান্ডলারের কলটি বাতিল করার ক্ষমতা থাকতে হবে:

$("button").click(function(e){
    if(bSomeConditional)
       e.stopImmediatePropagation();//Don't execute the widget's handler
}).each(function () {
    var aClickListeners = $._data(this, "events").click;
    aClickListeners.reverse();
});

7

সাধারণত হ্যান্ডলারটি সাধারণত বেঁধে রাখুন এবং তারপরে চালান:

element.data('events').action.reverse();

উদাহরণস্বরূপ:

$('#mydiv').data('events').click.reverse();

2
কাজ করে না, তবে এটি $._data(element, 'events')[name].reverse()কাজ করে
অ্যাটেনজিওন

7
function bindFirst(owner, event, handler) {
    owner.unbind(event, handler);
    owner.bind(event, handler);

    var events = owner.data('events')[event];
    events.unshift(events.pop());

    owner.data('events')[event] = events;
}

3

আপনি এরকম কিছু চেষ্টা করতে পারেন:

/**
  * Guarantee that a event handler allways be the last to execute
  * @param owner The jquery object with any others events handlers $(selector)
  * @param event The event descriptor like 'click'
  * @param handler The event handler to be executed allways at the end.
**/
function bindAtTheEnd(owner,event,handler){
    var aux=function(){owner.unbind(event,handler);owner.bind(event,handler);};
    bindAtTheStart(owner,event,aux,true);

}
/**
  * Bind a event handler at the start of all others events handlers.
  * @param owner Jquery object with any others events handlers $(selector);
  * @param event The event descriptor for example 'click';
  * @param handler The event handler to bind at the start.
  * @param one If the function only be executed once.
**/
function bindAtTheStart(owner,event,handler,one){
    var eventos,index;
    var handlers=new Array();
    owner.unbind(event,handler);
    eventos=owner.data("events")[event];
    for(index=0;index<eventos.length;index+=1){
        handlers[index]=eventos[index];
    }
    owner.unbind(event);
    if(one){
        owner.one(event,handler);
    }
    else{
        owner.bind(event,handler);
    }
    for(index=0;index<handlers.length;index+=1){
        owner.bind(event,ownerhandlers[index]);
    }   
}

আমি মনে করি "মালিকরা" কেবল "হ্যান্ডলার" হওয়া উচিত
জোরিল

1

আমার একই সমস্যা আছে এবং আমি এই বিষয়টি পেয়েছি। উপরের উত্তরগুলি সেই সমস্যাগুলি সমাধান করতে পারে তবে আমি তাদের ভাল পরিকল্পনা বলে মনে করি না।

আসল পৃথিবী নিয়ে চিন্তা করা যাক।

যদি আমরা এই উত্তরগুলি ব্যবহার করি তবে আমাদের কোড পরিবর্তন করতে হবে। আপনি আপনার কোড শৈলী পরিবর্তন করতে হবে। এটার মতো কিছু:

মূল:

$('form').submit(handle);

টাট্টু:

bindAtTheStart($('form'),'submit',handle);

সময় হিসাবে, আপনার প্রকল্প সম্পর্কে চিন্তা করুন। কোডটি কুৎসিত এবং পড়ার পক্ষে কঠিন! anthoer কারণ সহজ সর্বদা ভাল। আপনার যদি 10 বাইন্ডএস্টস্টার্ট থাকে তবে এটি কোনও বাগ থাকতে পারে না। আপনার যদি 100 বাইন্ডএটস্টার্ট থাকে, আপনি কি সত্যই নিশ্চিত যে আপনি এগুলি সঠিক ক্রমে রাখতে পারেন?

সুতরাং যদি আপনাকে একই ইভেন্টগুলিকে একাধিক আবদ্ধ করতে হয় I আমি মনে করি সর্বোত্তম উপায় হ'ল জেএস-ফাইল বা জেএস-কোড লোড ক্রম নিয়ন্ত্রণ। jquery সারি হিসাবে ইভেন্টের ডেটা পরিচালনা করতে পারে। অর্ডারটি প্রথম-ইন, প্রথম-আউট। আপনার কোনও কোড পরিবর্তন করার দরকার নেই। শুধু লোড ক্রম পরিবর্তন করুন।


0

এই এখানে আমার শট, jQuery এর বিভিন্ন সংস্করণ আবরণ:

// Binds a jQuery event to elements at the start of the event chain for that type.
jQuery.extend({
    _bindEventHandlerAtStart: function ($elements, eventType, handler) {
        var _data;

        $elements.bind(eventType, handler);
        // This bound the event, naturally, at the end of the event chain. We
        // need it at the start.

        if (typeof jQuery._data === 'function') {
            // Since jQuery 1.8.1, it seems, that the events object isn't
            // available through the public API `.data` method.
            // Using `$._data, where it exists, seems to work.
            _data = true;
        }

        $elements.each(function (index, element) {
            var events;

            if (_data) {
                events = jQuery._data(element, 'events')[eventType];
            } else {
                events = jQuery(element).data('events')[eventType];
            }

            events.unshift(events.pop());

            if (_data) {
                jQuery._data(element, 'events')[eventType] = events;
            } else {
                jQuery(element).data('events')[eventType] = events;
            }
        });
    }
});

0

কিছু বিশেষ ক্ষেত্রে, যখন ক্লিক ইভেন্টগুলি কীভাবে আবদ্ধ হয় আপনি তা পরিবর্তন করতে পারবেন না (অন্যের কোড থেকে ইভেন্টের বাইন্ডিংগুলি তৈরি করা হয়) এবং আপনি এইচটিএমএল উপাদানটি পরিবর্তন করতে পারেন, এখানে একটি সম্ভাব্য সমাধান রয়েছে ( সতর্কতা : এটি বাঁধাই করার প্রস্তাবিত উপায় নয় ) ইভেন্টস, অন্যান্য বিকাশকারীরা এর জন্য আপনাকে হত্যা করতে পারে):

<span onclick="yourEventHandler(event)">Button</span>

এই বাইন্ডিংয়ের সাহায্যে আপনার ইভেন্ট হ্যান্ডারটি প্রথমে যুক্ত হবে, তাই এটি প্রথমে কার্যকর করা হবে।


এটি কোনও সমাধান নয়, এটি কোনও সমাধানের ইঙ্গিত। আপনি কি পরামর্শ দিচ্ছেন যে এই "অন্লিক" হ্যান্ডলারটি এমন উপাদান চলছে যা ইতিমধ্যে একটি (jQuery) হ্যান্ডলার রয়েছে, বা আপনার <span> উপাদানটি jQuery হ্যান্ডলারের সাথে মোড়ানো ?
অ্যাসপেক্স

-2

JQuery 1.5 প্রতিশ্রুতি পরিচয় করিয়ে দেয়, এবং মৃত্যুদন্ড কার্যকর করার আদেশ নিয়ন্ত্রণ করতে আমি এখানে সবচেয়ে সহজ প্রয়োগ করেছি implementation Http://api.jquery.com/jquery.when/ এ সম্পূর্ণ ডকুমেন্টেশন

$.when( $('#myDiv').css('background-color', 'red') )
 .then( alert('hi!') )
 .then( myClickFunction( $('#myID') ) )
 .then( myThingToRunAfterClick() );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.