2012-03-23 8 views
6

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

.processing 
{ 
    background-color: #ff0000; 
} 

<div id="mydiv"> 
    Processing 
</div> 

स्क्रिप्ट:

$("#mydiv").addClass("processing"); 
// Do some long running processing 
$("#mydiv").removeClass("processing"); 

मैं naively सोचा था कि वर्ग div पर लागू किया जाएगा और UI को अपडेट किया जाएगा। हालांकि, ब्राउज़र में इसे चलाने (फ़ायरफ़ॉक्स में कम से कम) div को कभी भी हाइलाइट नहीं किया जाता है। क्या कोई मुझे समझा सकता है कि मेरा div क्यों हाइलाइट नहीं हुआ? वर्ग जोड़ा जाता है, प्रसंस्करण होता है और फिर वर्ग हटा दिया जाता है; UI को बीच में अपडेट नहीं किया गया है और उपयोगकर्ता लाल पृष्ठभूमि को कभी नहीं देखता है।

मुझे पता है कि जेएस एकल-थ्रेडेड है लेकिन मुझे हमेशा लगता है कि ब्राउजर प्रतिपादन डीओएम अपडेट होने पर समकालिक रूप से चलाएगा। क्या मेरी धारणा गलत है?

और सबसे महत्वपूर्ण बात यह है कि इस प्रभाव को प्राप्त करने के लिए अनुशंसित तरीका क्या है? धीमी प्रसंस्करण एसिंक्रोनस बनाने और कॉलबैक के साथ काम करने के लिए मुझे setTimeout का उपयोग करने का नतीजा है? एक बेहतर तरीका होना चाहिए क्योंकि मुझे वास्तव में यहां एसिंक व्यवहार की आवश्यकता नहीं है; मैं सिर्फ यूआई को रीफ्रेश करना चाहता हूं।

संपादित करें:

JSFiddle: http://jsfiddle.net/SE8wD/5/

+1

मेरा मानना ​​है कि इस तरह के परिवर्तन सीधे इसे डोम पर लाएंगे, लेकिन ब्राउजर तब तक इंतजार करेगा जब तक कि कोई भी पुनर्भुगतान करने से पहले जावास्क्रिप्ट निष्पादन "निष्क्रिय" न हो। – pimvdb

+0

"कुछ लंबी चल रही प्रसंस्करण करें" में कुछ असीमित कॉल है? (AJAX, settimeout आदि) –

+0

मैं वास्तव में नहीं देख सकता कि आपका कोड कहां गलत है, क्योंकि यह आपके द्वारा पोस्ट की गई चीज़ों के ठीक लगता है। शायद आपकी बाहरी सीएसएस फ़ाइल में कुछ 'महत्वपूर्ण' है। क्या आप वाकई कक्षा में शामिल हो गए हैं (क्या आपने फ़ायरबग के माध्यम से इसका निरीक्षण किया है) और क्या प्रक्रिया वास्तव में उस समय तक ले जाती है? हो सकता है कि यह बहुत तेज़ होता है –

उत्तर

0

Force a redraw (ध्यान दें, आप पाश पुनरावृत्तियों की संख्या tweak करने के लिए अपने स्वयं के पीसी पर आप एक उचित देरी देने के लिए आवश्यकता हो सकती है)। वैकल्पिक रूप से, Soren's code का उपयोग करें क्योंकि यूआई थ्रेड पर प्रसंस्करण खराब लगता है ...

+0

हालांकि, इस समय jQuery प्लगइन्स नीचे लगते हैं। एक विकल्प जोड़ा गया। यह हो सकता है कि आपको 'n.parentNode.removeChild (n)' को स्थगित करने की आवश्यकता नहीं है; यदि हां, तो मेरा जवाब संपादित करने के लिए स्वतंत्र महसूस करें। –

+0

मैंने बिना किसी सफलता के अपने जेएसफ़िल्ड पर यह कोशिश की। मैं स्पष्ट रूप से इसका उपयोग ठीक से नहीं कर रहा हूं। क्या आप कृपया फिडल में जोड़ सकते हैं? – njr101

+0

क्षमा करें, लेकिन पहेली काम नहीं करती है। कक्षा लागू होती है और फिर एक स्क्रिप्ट त्रुटि के साथ स्क्रिप्ट aborts। "समाप्त" संदेश कभी प्रदर्शित नहीं होता है। – njr101

1

मैं एक वज़न स्क्रिप्ट के लिए ब्राउज़र को फ्रीज करने की अनुशंसा नहीं करता हूं। इस मामले में मैं फ्रीज ब्राउज़र और डोम के लिए कोड को बदलना पसंद करता हूं। यदि आपके कोड में कुछ लूप है, तो आप विलंब के साथ फ़ंक्शन को कॉल कर सकते हैं (setInterval का उपयोग करके) और कुछ स्टेटस वैरिएबल कहीं स्टोर करें। उदाहरण के लिए:

for(var i=0; i<1000000; i++) { 
    // do something 
} 

किया जा सकता है:

var i = 0; 
var intervalID; 
var _f = function() { 
    // do something 
    i++; 
    if(i==1000000) clearInterval(intervalID); 
} 
intervalID = setInterval(_f,1); 

या इसी तरह की और अधिक अनुकूलित के बारे में कुछ। आपका कोड थोड़ा और जटिल, और धीमा होगा .. लेकिन इसलिए आप ब्राउज़र फ्रीज को रोकते हैं और आप उन्नत प्रीलोड स्टेटस बार बना सकते हैं।

+0

धन्यवाद, जब मैंने 'सेटटाइमआउट' का उल्लेख किया तो मेरा यही मतलब था। मुझे एहसास है कि मैं ऐसा कर सकता हूं लेकिन मैं एसिंक कॉल की अतिरिक्त जटिलता से बचने की उम्मीद कर रहा था। यह अन्य समस्याओं की एक पूरी कक्षा खोलता है जहां एसिंक कॉलबैक होता है जब राज्य अनिश्चित है। – njr101

+0

मुझे पता है। आप वेब वर्कर http://www.html5rocks.com/en/tutorials/workers/basics/ –

+0

लिंक के लिए धन्यवाद भी देख सकते हैं। दिलचस्प सामान, लेकिन दुर्भाग्य से मेरी मदद नहीं करेगा क्योंकि मुझे क्रॉस-ब्राउज़र समर्थन की आवश्यकता है। – njr101

1

आपको शायद इस तरह की एक अलग घटना में प्रसंस्करण को बाहर रखना चाहिए;

$("#mydiv").addClass("processing"); 
setTimeout(function(){ 
    // This runs as a seperate event after 
    // Do some long running processing 
    $("#mydiv").removeClass("processing"); 
},1); 

इस तरह ब्राउज़र, processing के साथ स्क्रीन पुनः बनाने चाहिए, जबकि लंबे समय से चल रहा है कदम एक अलग घटना के रूप में शुरू होगा, और जब किया प्रसंस्करण संदेश को हटा दें।

+0

धन्यवाद, मुझे यही संदेह है। मुझे उम्मीद थी कि इस बल से बचने के लिए ब्राउजर को डीओएम में बदलाव के बाद फिर से प्रस्तुत करना होगा। – njr101

+0

चेतावनी - मुझे लगता है कि यह 5 एमएमएस टाइमआउट के बाद काम करना शुरू कर देता है - कुछ भी छोटा और क्रोम अभी भी इंतजार कर रहा है। – user2486570

+0

@ user2486570 - मुझे शक है - जेएस एकल थ्रेडेड इवेंट लूप है - इसलिए इसमें केवल उन रेस स्थितियां हैं जिन्हें आप स्वयं बनाते हैं - यदि आपको 5ms समस्या दिखाई देती है तो शायद यह है कि आपके पास टाइमर या किसी अन्य के साथ चल रहा है डोम तैयार घटना जो आपके दूसरे कोड से विवादित है। – Soren

0

ब्राउज़र फिर से पुनर्निर्मित करने और कब रीफ्लो करने के बारे में काफी स्वतंत्र है। विभिन्न इंजन अलग-अलग व्यवहार दिखाएंगे। आगे पढ़ने के लिए, When does reflow happen in a DOM environment? देखें। आपके उदाहरण में, ब्राउज़र आपको कक्षा जोड़ने और उसके बाद सीधे इसे हटाने को देखता है, इसलिए वह कुछ भी दिखाई नहीं दे सकता है।

इससे बचने के लिए, आप एक बल-रेड्रो-हैक लागू कर सकते हैं, या वेबकॉर्कर्स या सेटटाइमआउट या कुछ के साथ अपनी गणना अतुल्यकालिक बना सकते हैं।

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