2011-02-07 49 views
21

我加載(大)動態圖像繪製成HTML5畫布,這樣的事情:取消在HTML5的瀏覽器單一的圖像請求

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

但每過一段時間想取消圖像完全請求

我想出的唯一方法是將src設置爲''。即

t.src = '' 

這適用於許多瀏覽器,但似乎只有Firefox實際上取消了圖像的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/ – 2011-02-07 20:55:39

+1

正確...一些瀏覽器正在請求網頁的網址(或base url)試圖用`src =''`加載圖像。在Firefox下,設置`t.src = null`也會取消請求,但是對其他人不做任何處理。較新的(當前工作)規範說(在某些情況下)[應該引發錯誤](http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1 .html#update-the-image-data)... kindof。 – Amir 2011-02-07 23:01:43

+3

在Firefox中將`src`設置爲嵌入式圖像也會取消以前的請求:`t.src ='data:image/gif; base64,R0lGOD ...`在[this fiddle]中看到它(http:// jsfiddle。 net/amirshim/F4HbT/21 /) – Amir 2011-02-07 23:16:47

回答

13

這是我設法使其在所有現代瀏覽器(Chrome,Safari,Mobile-Safari,Firefox和IE9)中都能正常工作的唯一方法。

  • 加載一個空和隱藏iframe
  • 追加一個image tagbodyiframe
  • img.onload完成後,您可以使用圖像DOM元素繪製爲HTML5畫布drawImage()
  • 如果要取消加載,請在iframecontentWindow(或IE中的contentDocumentexecCommand("stop", false))上發出stop()
  • 取消圖片加載後,您可以重新使用iframe加載更多圖片。

我在GitHub上創建了這個類,並把CoffeeScript的代碼(和它的編譯的JavaScript): Cancelable Html5 Image Loader

如果你想用它玩,我還創建了一個jsfiddle to test it out。記得啓動Fiddler2(或類似的東西),看看實際的網絡請求是否真的被取消。

4

您可以嘗試window.stop()來停止所有請求,但不是單個請求。在IE中,它不是window.stop(),它是document.execCommand(「Stop」,false)。

如果你有其他需求明智的東西,那麼這樣做會干擾它。 (你會後續重新請求你仍然想要的資源,但這太辛苦了)。


所以,如果你想停下來一個大的圖像一個請求,你可以做的是圖像加載到文檔中隱藏的iframe內。 IFRAME的onload事件可以用來將圖像加載到主文檔中,到那時它應該被緩存(假設你已經配置了緩存指令)。

如果圖片過長,則可以訪問IFRAME的contentWindow併發出停止命令。

您需要擁有儘可能多的IFRAME元素,因爲可以同時請求圖像。

+0

「但不是個人的」......你可以支持這個嗎?您提供的其他信息已經在問題中陳述並鏈接到了。 – Amir 2011-02-08 22:52:57

2

我懷疑有一種跨瀏覽器的方式可以在沒有黑客的情況下做到這一點。一個建議是向服務器端腳本發出AJAX請求,該腳本返回圖像的Base64編碼版本,然後您可以將其設置爲src屬性。然後,如果您決定取消加載圖像,則可以取消該請求。如果你想逐漸顯示圖像,這可能很困難。

2

我實際上有同樣的問題,並做了一些測試。

我已經做了一些測試iframes並取得了一些成功。經過Firefox 3.6和Chrome測試。對於我使用的9個15Mb的圖像。有了img預加載,我多次殺死了我的firefox(是的,在這臺計算機上沒有太多的記憶),使用img「暫停」動作並不會阻止圖像加載,如果請求已經開始,iframes暫停動作真的會停止下載(如我刪除iframe)。下一步將用XMLHttpRequests進行測試。由於我的測試代碼的這個版本正在使用圖片url的braowser緩存行爲來防止第二次加載,並且這也適用於ajax請求。但也許與iframe我可以找到一種方法來從iframe中直接加載的圖像中檢索二進制數據(限制在相同的域名url)。

這是我的測試代碼(非常快的瀏覽器,可太多的非常大的圖像殺死你的Firefox):

// 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'); 
      }); 
    }); 
}); 

編輯,這裏是fillde來測試它:http://jsfiddle.net/wPr3x/