2011-09-18 12 views
17

मुझे नहीं पता कि यह घोंसला सही है या नहीं? लेकिन मुझे पता है कि एक दूसरे के अंदर कई काम करने के लिए यह एक अच्छा कोड नहीं है। अधिकांश jQuery विधियों में कॉलबैक फ़ंक्शन होता है जिसे हम वहां पर कॉलबैक डाल सकते हैं। लेकिन जब हम किसी अन्य कॉलबैक के अंदर कॉलबैक करते हैं और इसे जारी रखते हैं और गहरे और गहरे होते हैं तो ऐसा लगता है कि कोड कम पठनीय हो सकता है और शायद कम डिबगबल हो सकता है।jQuery कोड को बहुत अधिक घोंसले कार्यों से कैसे रोकें?

उदाहरण के लिए यदि मैं एक दूसरे के बाद कुछ एनिमेशन करना चाहता हूं तो मुझे प्रत्येक एनीमेशन को कॉल करना होगा जिसे मैं कॉलबैक फ़ंक्शन में किसी अन्य के बाद आना चाहता हूं। यह कॉलबैक फ़ंक्शन में गहरा और गहरा होगा। एक 5 चरणों एनीमेशन मैं एक 5 स्तर कॉल स्टैक करना है करने के लिए

$('#t').animate({height: 400}, 500, function(){ 
    $(this).animate({height: 200}, 500, function(){ 
     $(this).animate({width: 300}, 500, function(){ 
      $(this).animate({height: 300}, 500, function(){ 
       $(this).animate({'border-radius': '50px'}, 500, function(){ 
        //and so on... 
       }); 
      }); 
     }); 
    }); 
}); 

: इस उदाहरण (fiddle) को देखो। तो मेरा सवाल यह है कि आप इससे कैसे बचते हैं? मुझे अपने नोड.जेएस कार्यों में भी एक ही समस्या थी।

अद्यतन: मुझे पता है कि jQuery फ़ंक्शन में चिनिंग सुविधा है लेकिन यह समस्या का समाधान नहीं करती है। क्योंकि आप श्रृंखला के बीच में कुछ नहीं कर सकते हैं। आप $(selector').animate().animate()... की तरह कोड के ऊपर लिख सकता है, लेकिन आप इस के लिए एक ही नहीं कर सकते:

$(selector).doQ(anim1, anim2, myfunc1, anim3, myfunc2)... 

लेकिन दुर्भाग्य से jQuery एक API की जरूरत नहीं है:

$('#t').animate({height: 400}, 500, function(){ 
     console.log('step 1 done: like a boss'); 
     $(this).animate({height: 200}, 500, function(){ 
      console.log('step 2 done: like a boss'); 
      $(this).animate({width: 300}, 500, function(){ 
       console.log('step 3 done: like a boss'); 
       $(this).animate({height: 300}, 500, function(){ 
        console.log('step 4 done: like a boss'); 
        $(this).animate({'border-radius': '50px'}, 500, function(){ 
         //and so on... 
        }); 
       }); 
      }); 
     }); 
    }); 

आदर्श समाधान इस तरह एक कोड होगा इस तरह (मेरे ज्ञान के लिए)।

+0

मुझे नहीं लगता कि इस तरह घोंसले के कार्यों में कोई समस्या है। – Nathan

+3

@ नाथन: वास्तव में? उस गहरे घोंसले वाले कोड को डिबगिंग, रखरखाव और पढ़ने का प्रयास करें। –

+0

@ एंड्रयू मेरा मतलब है कि मुझे लगता है कि यह काम करेगा। मैंने सोचा कि वह पूछ रहा था कि यह उचित है या नहीं। और हां, डीबग करना, पढ़ना और बनाए रखना बहुत मुश्किल है। – Nathan

उत्तर

23

* "आदर्श समाधान एक कोड इस तरह होगा:

$ (चयनकर्ता) .doQ (anim1, anim2, myfunc1, anim3, myfunc2) ..."*

यह काफी आप क्या चाहते हैं नहीं है, लेकिन jQuery queue()[docs] विधि है:

$(selector).animate({height: 400}, 500) 
      .animate({height: 200}, 500) 
      .queue(myfunc1) 
      .animate({width: 300}, 500) 
      .queue(myfunc2); 

तुम बस सुनिश्चित करें कि आपके कार्यों कतार जारी जब वे से काम हो गया बनाने की जरूरत है

function myfunc1() { 
    // your code 
    $(this).dequeue(); 
} 

या आप एक गुमनाम समारोह में अपने कार्यों लपेट कर सकते हैं और आह्वान फिर वहाँ विपंक्ति:

विधि का उपयोग
$(selector).animate({height: 400}, 500) 
      .animate({height: 200}, 500) 
      .queue(function(nxt) { 
       myfunc1(); 
       $(this).dequeue(); 
      }) 
      .animate({width: 300}, 500) 
      .queue(function(nxt) { 
       myfunc2(); 
       nxt(); // alternate way to dequeue 
      }); 
+0

यह, लेकिन myfunc1 को 'अगली' तर्क लेना चाहिए और 'अगला() चलाएं;' जब यह हो या यह जारी नहीं रहेगा। – evan

+0

हा, मैंने अभी भी यह लिखा है;) +1 –

+0

@evan: मेरे अपडेट देखें, हालांकि आप पारित तर्क के बजाय '.dequeue()' का उपयोग कर सकते हैं। – user113716

0

आप क्या कर सकते एक नाम के साथ कार्यों को परिभाषित है, और उन्हें एक और समारोह के अंदर संदर्भ, उदाहरण के लिए है

var clicka = function(){ 
    alert("I got clicked after t.") 
    } 
    var clickt = function(){ 
     alert("I got clicked!") 
     $('#a').click(clicka) 
    } 
    $('#t').click(clickt); 
4

के बारे में पढ़ें JQuery के Deferred Object

यह एक chainable उपयोगिता उद्देश्य यह है कि कर सकते हैं है कॉलबैक कतारों में एकाधिक कॉलबैक पंजीकृत करें, कॉलबैक कतारों का आह्वान करें, या सफलता या किसी भी सिंक्रोनस या असिंक्रोनस फ़ंक्शन की विफलता स्थिति को रिले करें।

यदि आपकी कॉलबैक केवल एनीमेशन हैं, तो बस उन्हें चेन करें और JQuery की FX कतार का उपयोग करें।

+0

मेरा प्रश्न इस स्थिति के बारे में है कि कोई * कॉल वापस नहीं है * ... – Mohsen

7

jQuery कतारों पर पढ़ें। आपका कोड भी इस तरह लिखा जा सकता है:

$('#t') 
    .animate({height: 400}, 500) 
    .animate({height: 200}, 500) 
    .animate({width: 300}, 500) 
    .animate({height: 300}, 500) 
    .animate({'border-radius': '50px'}, 500); 

पहले एनीमेशन तुरंत चलाया जाता है, लेकिन दूसरों "fx" कतार पर रख दिया और बदले में क्रियान्वित कर रहे हैं जब दूसरे खत्म।

+0

मैंने अपना प्रश्न अपडेट किया। जरा देखो तो। मुझे पता है कि कैसे काम करता है ... – Mohsen

+0

@Mohsen आप चेनिंग दृष्टिकोण और कॉलबैक को जोड़ सकते हैं ... – lonesomeday

+0

तो मेरा सवाल है कैसे ?! :) – Mohsen

4

jQuery ऑब्जेक्ट्स में डिफ़ॉल्ट कतार है। इस बेला का प्रयास करें: http://jsfiddle.net/TbkjK/1/

+0

क्या होगा यदि आप बीच में कुछ करना चाहते हैं? मेरे अपडेट किए गए प्रश्न को देखें – Mohsen

+0

यह कभी भी सवाल का हिस्सा नहीं था ... हालांकि, आप एनिमेशन को चेन कर सकते हैं, जब आप कुछ अतिरिक्त करना चाहते हैं तो कॉलबैक लें, फिर कॉलबैक में श्रृंखला समाप्त करें। – gislikonrad

2

एक छोटी सी क्लीनर रास्ता:

$('#t') 
    .animate({height: 400}, 500, animationDone) 
    .animate({height: 200}, 500, animationDone) 
    .animate({width : 200}, 500, animationDone) 
    .animate({height: 300}, 500, animationDone) 
    .animate({'border-radius': '50px'}, 500, animationDone); 


var logCount = 0; 
function animationDone(e) { 
    logCount++; 

    $("#t").html("Animation # " + logCount + " has completed!"); 
} 

सीधे शब्दों में logCount संख्या के आधार पर कुछ करना। उदाहरण here देखा जा सकता है।

+0

उत्तर के लिए धन्यवाद। मैं एक केस आधारित समाधान नहीं चाहता था। मैं सिर्फ प्रश्न की बेहतर समझ के लिए उदाहरण जोड़ता हूं – Mohsen

संबंधित मुद्दे