2011-02-07 15 views
21

मैं (बड़े) छवियों को लोड कर रहा हूँ गतिशील रूप से एक एचटीएमएल 5 कैनवास में आकर्षित करने के लिए, कुछ इस तरह:रद्द एचटीएमएल 5 ब्राउज़रों में एकल छवि अनुरोध

var t = new Image(); 
t.onload = ... 
t.src = 'http://myurl'; 

लेकिन हर एक बार थोड़ी देर में चाहते हैं छवि को रद्द करने पूरी तरह से अनुरोध करें।

एकमात्र तरीका जिस पर मैं आया था src'' पर सेट कर रहा है। अर्थात

t.src = '' 

यह कई ब्राउज़रों में काम करता है, लेकिन ऐसा लगता है कि केवल फ़ायरफ़ॉक्स वास्तव में छवि के लिए http अनुरोध को रद्द करता है।

मैंने कैशिंग को अक्षम करने और "मॉडेम गति अनुकरण" सक्षम करके Fiddler2 के साथ इसका परीक्षण किया। तब a fiddle to test canceling a image request. चल (मैं यह कैसे परीक्षण करने के लिए पर अन्य विचारों को सुनना पसंद करेंगे)

मुझे पता है कि सभी अनुरोधों (as in this question) को रद्द करने के तरीके हैं, लेकिन मैं केवल एक रद्द करना चाहते हैं।

ऐसा करने के लिए अन्य तरीकों (विशेष रूप से मोबाइल ब्राउज़र पर) पर कोई विचार?

+4

't.src = '' 'से सावधान रहें, यह कल्पना अस्पष्ट है कि क्या होना चाहिए। देखें http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/ –

+1

सही ... कुछ ब्राउज़र पृष्ठ के यूआरएल (या बेस यूआरएल) 'src =' ''के साथ छवि को लोड करने का प्रयास करें। फ़ायरफ़ॉक्स के तहत, 't.src = null' को सेट करने से अनुरोध रद्द हो जाता है, लेकिन दूसरों पर कुछ भी नहीं करता है। नया (वर्तमान कार्य) का नमूना कहता है (कुछ परिस्थितियों में) कि [इसे आतंक में आग लगनी चाहिए] (http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1 .html # अद्यतन-द-छवि-डेटा) ... kindof। – Amir

+3

फ़ायरफ़ॉक्स के नीचे एक इनलाइन छवि में 'src' को सेट करना भी पिछले अनुरोध को रद्द करता है: 't.src =' डेटा: छवि/gif; base64, R0lGOD ... 'इसे [इस पहेली] में देखें (http: // jsfiddle। नेट/अमिरीशिम/एफ 4 एचबीटी/21 /) – Amir

उत्तर

13

यह एकमात्र तरीका है कि मैं इसे सभी आधुनिक ब्राउज़रों (क्रोम, सफारी, मोबाइल-सफारी, फ़ायरफ़ॉक्स, और आईई 9) में काम करने में कामयाब रहा।

  • लोड एक खाली और छिपा iframe
  • iframe
  • में body के लिए एक image tag संलग्न जब img.onload पूरा करता है, आप के साथ एक HTML5 कैनवास को आकर्षित करने के लिए कि छवि डोम तत्व का उपयोग कर सकते drawImage()
  • अगर आप लोड को रद्द करना चाहते हैं, तो iframe के contentWindow (या execCommand("stop", false) पर contentDocument पर आईई) पर जारी करें। छवि लोड को रद्द करने के बाद
  • , आप अधिक छवियों को लोड करने के लिए iframe का पुन: उपयोग कर सकते हैं।

मैं GitHub पर इस बात के लिए एक वर्ग बनाया है, और coffeescript कोड डाल (और यह जावास्क्रिप्ट संकलित की गई हैं): Cancelable Html5 Image Loader

आप इसके साथ खेलने के लिए चाहते हैं, तो मैं भी एक jsfiddle to test it out बनाया। यह देखने के लिए कि वास्तविक नेटवर्क अनुरोध वास्तव में रद्द किया जा रहा है, फिडलर 2 (या ऐसा कुछ) शुरू करना याद रखें।

+0

+1 उस हैक के लिए धन्यवाद। पुराने आईई संस्करण के लिए कैनवास के बिना कुछ प्रदान करने का तरीका ढूंढना अच्छा लगेगा, शायद उन libs के साथ जो IE पर कैनवास समर्थन जोड़ते हैं। – regilero

+0

@ अमीर, हम इसे ओपनलेयर टाइल अनुरोधों में कैसे कार्यान्वित कर सकते हैं? – Myra

+0

@ एमीर मुझे एक ही समस्या मिली और आपकी स्क्रिप्ट को दोहराने की कोशिश की लेकिन मुझे काम करने के लिए iframe.contentWindow.stop() विधि नहीं मिल सकती है। क्या कोई तरीका है कि आप इसे देख सकते हैं? – Ming

4

आप सभी अनुरोधों को रोकने के लिए window.stop() को आजमा सकते हैं, लेकिन व्यक्तिगत नहीं। आईई में, यह window.stop() नहीं है document.execCommand ("रोकें", झूठा)।

यदि आपके पास अनुरोध के अनुसार अन्य सामान मिल रहे हैं, तो ऐसा करने से इसमें हस्तक्षेप होगा। (आप संसाधनों के पुन: अनुरोध के साथ अनुवर्ती करेंगे जो आप अभी भी चाहते हैं, लेकिन यह कड़ी मेहनत की तरह बहुत अधिक है)।


तो अगर आप एक बड़ी छवि के लिए एक अनुरोध को रोकने के लिए चाहता था, एक छिपा iframe के भीतर एक दस्तावेज़ में छवि को लोड है कि आप क्या कर सकता है। IFRAME की ऑनलोड घटना का उपयोग मुख्य दस्तावेज़ में छवि को लोड करने के लिए किया जा सकता है, जिसके द्वारा इसे कैश किया जाना चाहिए (मान लें कि आपके पास ऐसा करने के लिए कॉन्फ़िगर किए गए कैशिंग निर्देश हैं)।

यदि छवि बहुत अधिक समय ले रही है, तो आप IFRAME की सामग्री तक पहुंच सकते हैं और उस पर स्टॉप कमांड जारी कर सकते हैं।

आपको कई IFRAME तत्वों की आवश्यकता है क्योंकि छवियां हैं जिनसे अनुरोध किया जा सकता है।

+0

"लेकिन व्यक्तिगत नहीं" ... क्या आप इसे वापस कर सकते हैं? आपके द्वारा प्रदान की गई शेष जानकारी पहले से ही बताई गई थी और प्रश्न में जुड़ा हुआ था। – Amir

+0

आप विंडो के लिए सभी अनुरोधों को केवल प्रगति पर रोक सकते हैं। जो मुझे एक विचार देता है, मेरे उत्तर में अतिरिक्त जानकारी जोड़ा गया है! –

2

मुझे संदेह है कि यह हैक के बिना ऐसा करने के लिए एक क्रॉस-ब्राउज़र तरीका है। एक सुझाव है कि एक सर्वर-साइड स्क्रिप्ट के लिए AJAX अनुरोध करना है जो छवि के बेस 64 एन्कोडेड संस्करण को लौटाता है जिसे आप src विशेषता के रूप में सेट कर सकते हैं। फिर आप छवि को लोड करना रद्द करने का निर्णय लेते हैं तो आप इस अनुरोध को रद्द कर सकते हैं। यदि आप छवि को क्रमिक रूप से दिखाना चाहते हैं तो यह मुश्किल हो सकता है।

+1

महान विचार, लेकिन इसके साथ जुड़े कुछ समस्याएं हैं। पहला यह है कि स्थानांतरित डेटा की मात्रा 33% अधिक है। (बेस 64: 24 बिट्स -> 32 बिट्स)। फिर (विशेष रूप से मोबाइल ब्राउज़र पर), यह जावास्क्रिप्ट पर बहुत मेमोरी दबाव डालता है, क्योंकि डेटा को जेएस में एक स्ट्रिंग के रूप में संग्रहीत किया जाना चाहिए और उसके बाद बेस 64 डीकोडिंग का एक अतिरिक्त चरण भी है। बड़ी फ़ाइलों (200 के +) के लिए यह चोट पहुंचा सकता है। लेकिन यह निश्चित रूप से कुछ परिदृश्यों में अच्छी तरह से काम कर सकता है। – Amir

+0

यह एक अच्छा मुद्दा है। जब मैं इस विचार के साथ आया, तो मैंने उपर के बारे में नहीं सोचा था।स्पष्ट रूप से AJAX http://nagoon97.wordpress.com/2008/04/06/reading-binary-files-using-ajax/ का उपयोग करके बाइनरी फ़ाइलों को पढ़ने में कुछ प्रयास किए गए हैं। मैंने कभी यह कोशिश नहीं की है, लेकिन आप इसे संभवतः कर सकते हैं और फिर '' का उपयोग कर छवि खींच सकते हैं। –

2

मुझे वास्तव में एक ही समस्या है और कुछ परीक्षण किए हैं।

मैंने iframes के साथ कुछ परीक्षण किए हैं और कुछ सफलता प्राप्त की है। फ़ायरफ़ॉक्स 3.6 और क्रोम पर परीक्षण किया गया। परीक्षणों के लिए मैंने 1512b की 9 छवियों का उपयोग किया। आईएमजी प्रीलोडिंग के साथ मैंने कई बार अपने फ़ायरफ़ॉक्स को मार डाला (हाँ, इस कंप्यूटर पर ज्यादा मेमोटी नहीं), आईएमजी का उपयोग करके "निलंबन" कार्रवाई छवि लोडिंग को रोक नहीं देती है अगर अनुरोध शुरू हो गया है, तो iframes के साथ निलंबन कार्रवाई वास्तव में डाउनलोड को रोकती है (जैसा कि मैं iframe हटा दें)। अगला चरण XMLHttpRequests के साथ परीक्षण करेगा।चूंकि मेरे टेस्ट कोड का यह संस्करण ब्राउसर कैश व्यवहार का उपयोग कर रहा है, दूसरी यूआरएल को रोकने के लिए छवि यूआरएल बनाता है और यह AJAX अनुरोधों के साथ-साथ काम करता है। लेकिन शायद iframes के साथ मैं सीधे आईफ्रेम में लोड छवि से बाइनरी डेटा पुनर्प्राप्त करने का एक तरीका ढूंढ सकता हूं (उसी डोमेन यूआरएल पर सीमा के साथ)। fillde यह परीक्षण करने के लिए है

// jQuery.imageload.shared.list contains an array of oversized images url 
jQuery.each(imglist,function(i,imgsrc) { 

    name = 'imageload-frame'; 
    id = name + "-" + i; 
    // with img it is not possible to suspend, the get is performed even after remove 
    //var loader = jQuery('<img />').attr('name', name).attr('id',id); 
    var loader = jQuery('<iframe />').attr('name', name).attr('id',id); 

    //no cache on GET query taken from jQuery core 
    // as we really want to download each image for these tests 
    var ts = +new Date; 
    // try replacing _= if it is there 
    var ret = imgsrc.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 
    // if nothing was replaced, add timestamp to the end 
    imgsrc = imgsrc + ((ret == imgsrc) ? (imgsrc.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 

    loader.css('display', 'none').appendTo('body'); 
    loader.after(jQuery('<a>') 
      .text(' stop ') 
      .attr('href','#') 
      .click(function(){ 
       loader.remove(); 
       jQuery(this).text(' suspended '); 
      }) 
    ); 

    // start the load - preload 
    loader.attr('src',imgsrc); 

    // when preload is done we provide a way to get img in document 
    loader.load(function() { 
     jQuery(this).next("a:first") 
      .text(" retrieve ").unbind('click') 
      .click(function() { 
       var finalimg = jQuery('<img />'); 
       // browser cache should help us now 
       // but there's maybe a way to get it direclty from the iframe 
       finalimg.attr('src',loader[0].src); 
       finalimg.appendTo('body'); 
      }); 
    }); 
}); 

संपादित और यहाँ:

यह मेरा परीक्षण कोड (वास्तव में क्रोम पर तेजी से, बहुत ज्यादा बहुत बड़ी छवियों के साथ अपने फ़ायरफ़ॉक्स को मार सकता है) है http://jsfiddle.net/wPr3x/

+0

तो करीब है, लेकिन एक समस्या है। किसी कारण से, जब छवि आईफ्रेम में लोड की जाती है, तो यह तुरंत कैश में उपलब्ध नहीं होती है। तो छवि दो बार लोड होने के समाप्त होता है। यहाँ खेलने के लिए एक पहेली है। http://jsfiddle.net/amirshim/na3UA/ fiddler2 प्रारंभ करें (एक पीसी पर) और देखें कि छवि को दो बार अनुरोध किया जा रहा है। यदि आप 'use_unique_name' को बंद करते हैं तो आप देखेंगे कि पूरे पृष्ठ को लोड होने पर पहली बार कैश किया जा रहा है। – Amir

+0

मैंने उस समस्या को हल करने का प्रयास करने के लिए एक नया प्रश्न बनाया: http://stackoverflow.com/questions/4981229/image-not-loading-from-cache-after-its-loaded-in-an-iframe – Amir

+0

वें fiddle पर उदाहरण मैं नहीं देखता कि आपने src विशेषता को सेट करने और iframe डालने के बाद लोड() कॉलबैक कहां सेट किया है। तो आपके पास यह लोड इवेंट हो सकता है जिसे "लगभग: रिक्त" या ऐसे लोड के लोड के बाद कहा जाता है, यानी खाली iframe बेस स्रोत। – regilero

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