jquery 在html5浏览器中取消单个图像请求

ngynwnxp  于 2023-01-04  发布在  jQuery
关注(0)|答案(4)|浏览(176)

我正在动态加载(大)图像以绘制到html5画布中,类似于以下内容:

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

但每隔一段时间就想完全取消图像请求
我想到的唯一方法是将src设置为''

t.src = ''

这在许多浏览器中都有效,但似乎只有Firefox真正取消了对图像的http请求。
我用Fiddler2测试了这个,禁用缓存,启用“emulate modem speed”,然后运行a fiddle to test canceling a image request.(我很想听听其他测试方法)
我知道可以取消所有请求(as in this question),但我只想取消一个。
有没有其他方法(特别是在移动的浏览器上)来做到这一点?

1cosmwyk

1cosmwyk1#

这是我设法让它在所有现代浏览器(Chrome、Safari、Mobile-Safari、Firefox和IE9)中工作的唯一方法。

  • 加载一个隐藏的空iframe
  • image tag附加到iframe中的body
  • img.onload完成时,你可以使用那个图像dom元素用drawImage()绘制到html5画布
  • 如果你想取消加载,在iframecontentWindow上发出stop()(或者在IE中在contentDocument上发出execCommand("stop", false))。
  • 在你取消一个镜像加载之后,你可以重新使用iframe来加载更多的镜像。

我为此创建了一个类,并将coffeescript代码(及其编译后的javascript)放在github上:Cancelable Html5 Image Loader
如果你想玩它,我还创建了一个jsfiddle to test it out,记得启动Fiddler 2(或类似的东西),看看实际的网络请求真的被取消了。

3pvhb19x

3pvhb19x2#

你可以尝试使用window.stop()来停止所有请求,但不能停止单个请求。在IE中,它不是window.stop(),而是document.execCommand(“Stop”,false)。
如果你有其他的事情要处理,那么这样做会干扰它(你会接着重新请求你仍然想要的资源,但这太像是艰苦的工作)。
因此,如果你想停止一个对大图像的请求,你可以做的是将图像加载到一个隐藏的IFRAME中的文档中,IFRAME的onload事件可以用来将图像加载到主文档中,到那时它应该被缓存(假设你已经配置了缓存指令)。
如果映像花费的时间太长,那么您可以访问IFRAME的contentWindow并向其发出stop命令。
IFRAME元素的数量需要与可以同时请求的图像的数量一样多。

jtw3ybtb

jtw3ybtb3#

我怀疑有没有一种跨浏览器的方法可以做到这一点。一个建议是向服务器端脚本发出 AJAX 请求,该脚本返回图像的Base64编码版本,然后可以将其设置为src属性。然后,如果您决定取消加载图像,则可以取消此请求。但是,如果您希望渐进地显示图像,这可能会很困难。

ve7v8dk2

ve7v8dk24#

实际上我也有同样的问题,做了一些测试。
我用iframes做了一些测试,并取得了一些成功。在Firefox 3.6和Chrome上测试。在测试中,我使用了9张15Mb的图片。使用img预加载,我杀死了我的Firefox好几次(是的,这台计算机上没有太多的内存),使用img的“暂停”动作并不能阻止图像加载,如果请求已经开始,使用iframe,暂停操作确实停止下载(因为我删除了iframe).下一步将使用XMLHttpRequests进行测试.因为我的测试代码的这个版本使用了braowser缓存行为来防止第二次加载,这对 AJAX 请求也同样有效.但是也许使用iframe我可以找到一种方法直接从iframe中加载的图像中检索二进制数据(限制相同域的url)。
这是我的测试代码(真的很快的Chrome,可能会杀死你的火狐太多非常大的图像):

// 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/

相关问题