[英]Cancel single image request in html5 browsers
我正在動態加載(大)圖像以繪制到html5畫布,如下所示:
var t = new Image();
t.onload = ...
t.src = 'http://myurl';
但每隔一段時間就想完全取消圖像請求 。
我想出的唯一方法是將src
設置為''
。 即
t.src = ''
這適用於許多瀏覽器,但似乎只有Firefox實際上取消了對圖像的http請求。
我通過禁用緩存並啟用“模擬調制解調器速度”來測試Fiddler2 。 然后運行小提琴來測試取消圖像請求。 (我很想聽聽關於如何測試這個的其他想法)
我知道有辦法取消所有請求( 如本問題所示 ),但我只想取消一個。
有關其他方式(特別是在移動瀏覽器上)的任何想法嗎?
這是我設法讓它在所有現代瀏覽器(Chrome,Safari,Mobile-Safari,Firefox和IE9)中運行的唯一方式。
iframe
image tag
附加到iframe
的body
img.onload
完成時,您可以使用該圖像dom元素繪制到帶有drawImage()
的html5畫布 iframe
的contentWindow
(或IE中的contentDocument
上的execCommand("stop", false)
上發出stop()
)。 我為此創建了一個類,並將coffeescript代碼(以及它的編譯javascript)放在github上: Cancelable Html5 Image Loader
如果你想玩它,我還創建了一個jsfiddle來測試它 。 記得啟動Fiddler2(或類似的東西),看看實際的網絡請求是否真的被取消了。
您可以嘗試使用window.stop()來停止所有請求,但不能停止單個請求。 在IE中,它不是window.stop()它是document.execCommand(“Stop”,false)。
如果你有其他的東西按要求進行,那么這樣做會干擾它。 (你會跟進對你仍然想要的資源的重新請求,但這太辛苦了)。
因此,如果您想停止對大圖像的單個請求,您可以做的是將圖像加載到隱藏的IFRAME中的文檔中。 IFRAME的onload事件可用於將映像加載到主文檔中,此時它應該被緩存(假設您已配置緩存指令)。
如果圖像花費的時間太長,那么您可以訪問IFRAME的contentWindow並向其發出停止命令。
您需要擁有盡可能多的IFRAME元素,因為可以同時請求圖像。
我懷疑是否有一種跨瀏覽器的方式來實現這一點,而不是黑客攻擊。 一個建議是向服務器端腳本發出一個AJAX請求,該腳本返回圖像的Base64編碼版本,然后您可以將其設置為src
屬性。 然后,如果您決定取消加載圖像,則可以取消此請求。 如果您想要逐步顯示圖像,這可能會很困難。
我實際上有同樣的問題並做了一些測試。
我已經用iframe進行了一些測試並取得了一些成功。 在Firefox 3.6和Chrome上測試過。 對於測試,我使用了9張15Mb的圖像 。 使用img預加載我幾次殺了我的firefox(是的,在這台計算機上沒有多少memoty),使用img“暫停”操作不會阻止圖像加載如果請求已經開始,iframes掛起動作真的停止下載(因為我刪除iframe)。 下一步將使用XMLHttpRequests進行測試。 由於此版本的測試代碼使用braowser緩存行為形成圖像URL以防止第二次加載,這也適用於ajax請求。 但也許使用iframe我可以找到一種方法直接從iframe中加載的圖像中檢索二進制數據(限制在相同的域URL上)。
這是我的測試代碼(在Chrome上真的很快,可能用太多非常大的圖像殺死你的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/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.