2012-08-13 17 views
15

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

I उत्तरदायी छवियों के लिए picturefill का उपयोग कर रहा हूँ। मेरे पास एक कॉलबैक है जिसे छवियों पर लोड इवेंट के लिए निकाल दिया गया है। तो जब भी कोई ब्राउज़र विंडो का आकार बदलता है तो कॉलबैक चलता है जैसे कि चित्रफिल के माध्यम से एक अलग छवि लोड की जाती है।

कॉलबैक के अंदर, मैं छवि डेटा को कैनवास के माध्यम से डेटाURL में परिवर्तित कर रहा हूं ताकि मैं स्थानीय डेटा में छवि डेटा को कैश कर सकूं ताकि यह ऑफ़लाइन होने पर भी उपयोगकर्ता के लिए उपलब्ध हो।

"ऑफलाइन" के बारे में हिस्सा नोट करें। यही कारण है कि मैं ब्राउज़र कैश पर भरोसा नहीं कर सकता। और एचटीएमएल 5 ऑफ़लाइन एप्लिकेशन कैश मेरी ज़रूरतों को पूरा नहीं करता है क्योंकि छवियां उत्तरदायी हैं। (एचटीएमएल ऑफ़लाइन एप्लिकेशन कैश के साथ उत्तरदायी छवियों की असंगतता के स्पष्टीकरण के लिए "Application Cache is a Douchebag" देखें।)

मैक पर फ़ायरफ़ॉक्स 14.0.1 पर, लोड छवि आग लग जाएगी यदि मैं ब्राउज़र को वास्तव में बड़ा आकार देता हूं और फिर इसका आकार बदलता हूं बड़ी छवि को पूरी तरह से लोड करने का मौका मिलने से पहले कुछ बार फिर से नीचे जाएं। यह फ़ायरबग कंसोल में "छवि भ्रष्ट या छंटनी" की रिपोर्टिंग समाप्त होता है, लेकिन अपवाद फेंकता है या त्रुटि ईवेंट ट्रिगर नहीं करता है। कोड में कोई संकेत गलत नहीं है। बस फायरबग कंसोल में। इस बीच, यह स्थानीय स्टोरेज में एक कटा हुआ छवि स्टोर करता है।

मैं इस समस्या को जावास्क्रिप्ट के भीतर कैसे विश्वसनीय और कुशलतापूर्वक पहचान सकता हूं ताकि मैं उस छवि को कैश न करूं?

यहाँ कैसे मैं picturefill divs के माध्यम से लूप img टैग कि picturefill द्वारा सम्मिलित किया गया है खोजने के लिए है:

var errorLogger = function() { 
     window.console.log('Error loading image.'); 
     this.removeEventListener('load', cacheImage, false); 
    }; 

    for(var i = 0, il = ps.length; i < il; i++){ 
     if(ps[ i ].getAttribute("data-picture") !== null){ 

      image = ps[ i ].getElementsByTagName("img")[0]; 
      if (image) { 
       if ((imageSrc = image.getAttribute("src")) !== null) { 
        if (imageSrc.substr(0,5) !== "data:") { 
         image.addEventListener("load", cacheImage, false); 
         image.addEventListener('error', errorLogger, false); 
        } 
       } 
      } 
     } 
    } 

और यहाँ क्या cacheImage() कॉलबैक की तरह लग रहा है:

var cacheImage = function() { 
    var canvas, 
     ctx, 
     imageSrc; 

    imageSrc = this.getAttribute("src"); 

    if ((pf_index.hasOwnProperty('pf_s_' + imageSrc)) || 
     (imageSrc.substr(0,5) === "data:") || 
     (imageSrc === null) || (imageSrc.length === 0)) { 
      return; 
    } 

    canvas = w.document.createElement("canvas"); 
    canvas.width = this.width; 
    canvas.height = this.height; 

    ctx = canvas.getContext("2d"); 
    ctx.drawImage(this, 0, 0); 
    try { 
     dataUri = canvas.toDataURL(); 
    } catch (e) { 
     // TODO: Improve error handling here. For now, if canvas.toDataURL() 
     // throws an exception, don't cache the image and move on. 
     return; 
    } 

    // Do not cache if the resulting cache item will take more than 128Kb. 
    if (dataUri.length > 131072) { 
     return; 
    } 

    pf_index["pf_s_"+imageSrc] = 1; 

    try { 
     localStorage.setItem("pf_s_"+imageSrc, dataUri); 
     localStorage.setItem("pf_index", JSON.stringify(pf_index)); 
    } catch (e) { 
     // Caching failed. Remove item from index object so next cached item 
     // doesn't wrongly indicate this item was successfully cached. 
     delete pf_index["pf_s_"+imageSrc]; 
    } 
}; 

अन्त में, यहाँ यूआरएल के साथ फायरबग में जो मैं देख रहा हूं उसका पूरा पाठ दोषी है:

छवि भ्रष्ट या छोटा कर दिया: http://www.example.com/pf/external/imgs/extralarge.png

+2

क्या यह '' तत्व पर 'त्रुटि' ईवेंट नहीं चलाता है? – MaxArt

+2

कोई पूछ सकता है कि आप ब्राउजर कैश को यह काम करने की बजाय स्थानीय स्टोरेज में अपनी खुद की छवि कैशिंग को कार्यान्वित करने का प्रयास क्यों कर रहे हैं? – jfriend00

+0

@ jfriend00 मैं ऑफ़लाइन उपयोग के लिए छवि को कैशिंग कर रहा हूं। मैंने इस सवाल में यह कहा, लेकिन मैंने इसे एक तरफ पसंद किया। मैंने ऑफलाइन बिट को अधिक जोर देने के लिए प्रश्न संपादित किया है। वैसे भी, अगला स्पष्ट सवाल यह है कि HTML5 ऑफ़लाइन एपकैचिंग का उपयोग क्यों नहीं करें। स्पष्टीकरण के लिए क्यों उत्तरदायी छवियों और एचटीएमएल 5 ऑफ़लाइन एपकैचिंग असंगत हैं, http://www.alistapart.com/articles/application-cache-is-a-douchebag/ – Trott

उत्तर

9

ऐसा लगता है कि जब img टैग की src विशेषता को बदलने, फायरफॉक्स एक load ईवेंट सक्रिय। यह एचटीएमएल 5 विनिर्देश के विपरीत है, जो says है कि यदि स्रोत विशेषता बदल दी गई है, तो प्रगति पर पहले से ही कोई अन्य fetch समाप्त हो जाना चाहिए (जो फ़ायरफ़ॉक्स करता है), और कोई ईवेंट नहीं भेजा जाना चाहिए। load ईवेंट केवल तभी भेजा जाना चाहिए जब fetch सफलतापूर्वक पूरा हो गया हो। तो मैं कहूंगा कि तथ्य यह है कि आपको load ईवेंट फ़ायरफ़ॉक्स बग है।

हालांकि, छवि पता होना चाहिए अगर यह पूरी तरह से उपलब्ध है या नहीं है, तो आप complete विशेषता का उपयोग करने की कोशिश कर सकते:

if (this.complete === false) { 
    return; 
} 

दुर्भाग्य से, फायरफॉक्स, बजाय this.completetrue लिए सेट है, ताकि एक नहीं है विकल्प या तो।

प्रत्येक बार जब आप src विशेषता को बदलना चाहते हैं तो नया <img> तत्व बनाने का सबसे अच्छा विकल्प हो सकता है।

+0

दुर्भाग्यवश, यह.com उस समय भी सच है, इसलिए यह समस्या के आसपास नहीं आती है। मुझे लगता है कि वहां क्या हो रहा है वह है .complete को सेट हो जाता है सच है, फ़ायरफ़ॉक्स कभी भी गलत नहीं होता है जब स्रोत बदल जाता है। Harrumph। HTML5 spec का उल्लेख करने के लिए धन्यवाद। मुझे इसे देखना होगा। मैंने सोचा कि यह इस पर संदिग्ध था, लेकिन यदि नहीं, तो शायद यह फाइल करने का समय है बग! – Trott

+0

दरअसल, मैंने इसे स्वयं करने की कोशिश की और 'पूरा' ध्वज 'सत्य' बना हुआ है, और यह केवल पढ़ने के लिए है, इसे मैन्युअल रूप से वापस नहीं बदला जा सकता है। तो या तो फ़ायरफ़ॉक्स को इस बग को ठीक करने के लिए प्रतीक्षा करें, या आप बना सकते हैं प्रत्येक बार जब आप 'src' बदलते हैं और पुराने को प्रतिस्थापित करते हैं तो एक नया' img' तत्व। –

+0

असल में, उदाहरण को आजमाते समय, मैंने देखा कि मुझे 'src' को बदलते समय 'लोड' ईवेंट नहीं मिला था और छवि पूरी तरह से लोड नहीं हुई थी। दोनों पीएनजी और जेपीजी छवियों का उपयोग करके, लिनक्स पर एफएफ 14.0.1 पर परीक्षण किया गया। मैंने बनाया [यह jsfiddl ई] (http://jsfiddle.net/GfKCf/5/) इसे आज़माने के लिए, फ़ायरबग खोलें और देखें कि कंसोल में कौन सी घटनाएं लॉग हैं। –

2

मैं आज इस मुद्दे से डूब गया था। सबकुछ ठीक काम कर रहा था (छवियों को अपेक्षित रूप से लोड किया गया था) सिवाय इसके कि फ़ायरफ़ॉक्स त्रुटि कंसोल में त्रुटि दिखाई दे रही है - हालांकि आईई या क्रोम में ऐसी कोई त्रुटि नहीं है।

मेरे मामले में मैं एक पूर्ण jquery हैंडलर में आंतरिक HTML के साथ एक div में एक छवि प्लगिंग कर रहा था। त्रुटियों को रोक दिया गया जब मैंने jquery कॉल को पूर्ववत किया:

var image_holder = new Image(); 
image_holder.src = img_path;//path of image that's going to be plugged in 

यह मेरे लिए काम करता है, लेकिन यह अभी भी कोई समझ नहीं आता है। मुझे लगता है कि यह समय के साथ कुछ करने के लिए है क्योंकि यह कोड उस कोड को प्राप्त करने से पहले लोड करने के लिए छवि को शुरू करता है जो वास्तव में पृष्ठ में प्लग करता है।

+0

यह मेरे लिए भी तय किया गया। अजीब! –