2008-12-04 14 views
5

पर कॉल नहीं कर रहा है सेटटाइमआउट फ़ंक्शन हमेशा मुझे परेशानी देता है। अभी मेरे पास एक ऐसा फ़ंक्शन है जो रिकर्सिव है (सेटटाइमआउट के माध्यम से स्वयं को कॉल करता है) और तत्वों की ऊंचाई को बदल देता है।जावास्क्रिप्ट का सेटटाइमआउट फ़ंक्शन

फ़ंक्शन दो तर्क भेजे गए हैं: तत्व को बदलने के लिए और तत्व अधिकतम ऊंचाई। फ़ंक्शन का उद्देश्य तत्व को प्रकट करना है, या निरंतर गति से "स्लाइड डाउन" करना है। मुझे पता है कि मैं शायद इस समस्या को jQuery के साथ हल कर सकता हूं, लेकिन मैं अपना खुद का काम करने की कोशिश कर रहा हूं।

function slide_down(element, max_height) 
{ 
    if(element.clientHeight < max_height) 
    { 
     var factor = 10; 
     var new_height = (element.clientHeight + factor >= max_height) ? max_height : (element.clientHeight + factor); 
     element.style.height = new_height + 'px'; 

     var func_call = 'slide_down(' + element + ', ' + max_height + ');'; 
     window.setTimeout(func_call, 10); 
    } 
} 

जब मैंने प्रारंभ में फ़ंक्शन शुरू किया है तो मैंने तर्कों का परीक्षण किया है। max_height 20 पर सेट है क्योंकि यह तत्व वांछित ऊंचाई है (मुझे यह मान .scrollHeight से मिला है)।

जब कार्य पूरा हो जाता है, तो मैं इसे तब तक कॉल करना चाहता हूं जब तक max_height तत्व की ऊंचाई न हो। मैं करता हूं कि इस सेटटाइमआउट कॉल के साथ:

var func_call = 'slide_down(' + element + ', ' + max_height + ');'; 
window.setTimeout(func_call, 10); 

और यह काम नहीं कर रहा है। यह काम करता है:

var func_call = 'alert(1);'; 
window.setTimeout(func_call, 10); 

मैंने फ़ंक्शन कॉल को सीधे सेटटाइमआउट कथन में डालने का भी प्रयास किया है, फिर भी काम नहीं करता है।

ध्यान दें कि तत्व की ऊंचाई पहले पुनरावृत्ति को बदलती है, फ़ंक्शन केवल स्वयं को कॉल नहीं करता है। तो तत्व चर सही ढंग से सेट किया गया है, और मैंने max_height को प्रदर्शित करने के लिए चेतावनी() का उपयोग किया जो भी सही है।

alert(func_call); 

अलर्ट इस:

slide_down([object HTMLParagraphElement], 20); 

उत्तर

19

जब आप ऐसा करते:

var func_call = 'slide_down(' + element + ', ' + max_height + ');'; 

आप एक स्ट्रिंग के लिए तत्व को परिवर्तित कर रहे हैं, तो अपने समय समाप्ति की तरह

slide_down("[Object]", 100); 

जो स्पष्ट रूप से काम नहीं करेगा दिखेगा।

आपको क्या करना चाहिए एक बंद करना है - यह थोड़ा जटिल है लेकिन मूल रूप से आप एक फ़ंक्शन बनाते हैं, और पुराने फ़ंक्शन से स्थानीय चर अभी भी नए फ़ंक्शन के भीतर उपलब्ध हैं।

function slide_down(element, max_height) 
{ 
    if(element.clientHeight < max_height) 
    { 
     var factor = 10; 
     var new_height = (element.clientHeight + factor >= max_height) ? max_height : (element.clientHeight + factor); 
     element.style.height = new_height + 'px'; 

     var func = function() 
     { 
      slide_down(element, max_height); 
     } 

     window.setTimeout(func, 10); 
    } 
} 

इसके अलावा 10 टाइमआउट के लिए थोड़ा सा छोटा है - मैं न्यूनतम 50 का उपयोग करने की अनुशंसा करता हूं।

+0

धन्यवाद। मैं इसकी तलाश में था। – HOT

1

मैं एक ऐसी ही अनुभव था। जब आप अगली बार तत्व पारित कर रहे हैं, तो यह फ़ंक्शन कॉल में स्ट्रिंग में परिवर्तित हो रहा है, इसलिए जब फ़ंक्शन चलता है, तो यह आपके इच्छित उद्देश्य के बजाय [ऑब्जेक्ट] .स्ट्रिंग या कुछ नामक तत्व ढूंढने का प्रयास करता है।

तत्व की आईडी लेने के लिए अपना फ़ंक्शन पैरामीटर बदलने का प्रयास करें और दस्तावेज़ करें .getElementById() फ़ंक्शन के अंदर पहली चीज़ को कॉल करें।

0

दो बातें:

1.setTimeout() जिसमें आप समारोह और मानकों के बजाय निष्पादित करने के लिए एक स्ट्रिंग पारित कॉल करने के लिए एक वैकल्पिक तरीका नहीं है। वास्तव में, the Gecko DOM manual states कि setTimeout() पर कॉल करने का आपका संस्करण अनुशंसित नहीं है।

बजाय

:

var func_call = 'slide_down(' + element + ', ' + max_height + ');'; 
window.setTimeout(func_call, 10); 

ऐसा करें:

window.setTimeout(slide_down, 10, element, max_height); 

अद्यतन: के रूप में RoBorg उल्लेख किया है, यह IE में काम नहीं कर सकता है, तो आप के रूप में अच्छी इसे अनदेखा कर सकते हैं।


2। मुझे एहसास है कि setTimeout() को उस फ़ंक्शन के भीतर से कॉल किया गया है जिसे setTimeout() द्वारा स्वयं कहा जाता है या तो अच्छी तरह से काम नहीं करता है या नहीं। मुझे लगता है कि आप इस तरह की कॉल को चेन कर रहे हैं क्योंकि आप कोड को बार-बार निष्पादित करना चाहते हैं? यदि हां, तो window.setInterval() क्या है।

+0

मोज़िला डोम मैनुअल गलत है ...? –

+0

हम्म मुझे लगता है कि मैं उस वाक्यविन्यास में कभी नहीं आया क्योंकि "ध्यान दें कि पहले वाक्यविन्यास में फ़ंक्शन में अतिरिक्त पैरामीटर पास करना इंटरनेट एक्सप्लोरर में काम नहीं करता है"। आपका पहला लिंक 404 से पहले आया था, या तो आपने संपादित किया था या यह एक गड़बड़ थी। -1 हटा दिया – Greg

+0

मैंने लिंक के साथ एक समस्या तय की, https सही स्वरूपित नहीं किया गया था। धन्यवाद। –

3

सबसे पहले, यह मेरे लिए setInterval चिल्लाती अगर आप अवधि अलग-अलग नहीं कर रहे हैं "अभी मैं एक समारोह है कि पुनरावर्ती है (setTimeout के माध्यम से ही कॉल) है।"

दूसरा, ऐसा इसलिए है क्योंकि तत्व संदर्भ के रूप में स्ट्रिंग कॉन्सट में तत्व संदर्भ खो जाता है .toString() "[ऑब्जेक्ट]" होगा। एक आईडी में गुजरने का प्रयास करें जिसे आप फिर से ढूंढ सकते हैं, संदर्भ को एक स्तर ऊपर संग्रहित कर सकते हैं, या (जैसे मैंने मैट बी पॉइंट आउट देखा है) विस्तारित विधि प्रपत्र।

1

आपके कोड के साथ समस्या यह है कि आप तत्व पैरामीटर को पार करने में विफल हैं।

बजाय:

 
var func_call = 'slide_down(' + element + ', ' + max_height + ');'; 

window.setTimeout(func_call, 10); 

कोशिश गुमनाम समारोह का उपयोग कर:

 

window.setTimeout(function() { 
    slide_down(element, max_height) 
}, 10); 

@ matt.b: setTimeout कॉल (जिस तरह से आप करते हैं) में गुजर तर्क IE में समर्थित नहीं है।

2

(Gregs जवाब देने के लिए विस्तार के रूप में) विधि लेखन का एक और अधिक सूक्ष्म तरीका:

function slide_down(element, max_height) 
{ 
    if(element.clientHeight < max_height) 
    { return; } 

    var factor = 10, 
     new_height = element.clientHeight + factor, 
     f = arguments.callee; 

    if(new_height > max_height) 
    { new_height = max_height; } 

    element.style.height = new_height + 'px'; 

    window.setTimeout(function() { f(element, max_height); }, 10); 
} 

इस नमूना कोड का वास्तविक लाभ arguments.callee का उपयोग है। इस तरह आप अपना काम नहीं तोड़ेंगे, क्या आप इसका नाम बदलने का फैसला कर सकते हैं। मैंने new_height वैल्यू असाइनिंग को भी आसानी से बनाया। पुराने कोड में समस्या यह है कि आपने element.clientHeight + factor दो बार किया, जो थोड़े अनैतिक है। इस मामले में आपके प्रदर्शन पर इसका कोई उल्लेखनीय प्रभाव नहीं है। लेकिन एक ही चीजों की गणना करने से बचने के लिए हमेशा अच्छा होता है, लेकिन बाद में उपयोग के लिए परिणाम संग्रहित करें।