使用ajax预加载图像

Rei*_*son 6 javascript ajax image preload

发现这种使用ajax预加载东西的技术:http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

window.onload = function() {
    setTimeout(function() {
        // XHR to request a JS and a CSS
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://domain.tld/preload.js');
        xhr.send('');
        xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://domain.tld/preload.css');
        xhr.send('');
        // preload image
        new Image().src = "http://domain.tld/preload.png";
    }, 1000);
};
Run Code Online (Sandbox Code Playgroud)

我注意到这个图像的'ajax'预加载实际上并不是真正的ajax.它与我多年来一直使用的相同,只是在新图像对象的源中设置url并让浏览器将其加载到缓存中.

现在假设有一个应用程序,如果它占用了一定的时间,我需要实际取消图像的预加载.只需将图像设置为src就没有好办法,不像xhr.abort()方法停止加载实际的xhr请求.

是否有任何理由做像下面这样的事情也不会预先加载图像并允许取消预加载请求?

function preload(url, timeout){
    this.canceltimeout = function(){
        clearTimeout(this.timeout);
        this.loaded = true;
        return false;
    }

    this.abort = function(){
        this.xhr.abort();
        this.aborted = true;
    }

    //creates a closure to bind the functions to the right execution scope
    this.$_bind = function(method){
        var obj = this;
        return function (e){ obj[method](e);};
    }

    //set a default of 10 second timeout
    if(timeout == null){
        timeout = 10000;
    }

    this.aborted = false;
    this.loaded = false;
    this.xhr = new XMLHttpRequest();
    this.xhr.onreadystatechange = this.$_bind('canceltimeout');
    this.xhr.open('GET', url);
    this.xhr.send('');
    this.timeout = setTimeout(this.$_bind('abort'), timeout);
}

var llama = new preload('/image.gif');
show_image();

function show_image(){
    if(llama.loaded){
        var l = new Image();
        l.src = '/image.gif';
        application.appendChild(l);
    }else if(llama.aborted){
        var l = document.createElement('p');
        l.innerHTML = 'image.gif got cancelled';
        application.appendChild(l);
    }else{
        setTimeout(show_image, 10);
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

goa*_*oat 5

主要缺点是,除非您已将Web服务器配置为提供将来的新鲜度信息(将来的一个ExpiresCache-control: max-agehttp标头),否则Web浏览器可能会在您设置image.src时向服务器发出第二个http请求,或者只是简单地实际使用文档中的图像.如果您的Web服务器已经发送了新鲜度验证标头(last-modified,或e-tag),那么该图像将不会被重新加载,但是要求服务器进行新鲜度验证的请求将会进行,这将浪费并增加该过程的延迟.

我不知道为什么,但是当你持有对Image()对象的引用时,浏览器真的喜欢缓存图像.

如果您在Web浏览器调试工具中观看网络面板,则大多数浏览器会发出前2个请求,但不会发出第3个请求.注释掉ajax回调中的代码,你会看到为#3做出的请求

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script>
var f = "0.png?" + (new Date); // 0.png should not have future freshness info headers

$.get(f, function() {
    var i = new Image();
    i.src = f;
});
setTimeout(function(){
    //#3
    var i = new Image();
    i.src = f;
}, 5000);
</script>
Run Code Online (Sandbox Code Playgroud)