0

我有这个脚本,它应该在加载图像时显示文本“正在加载...”,然后在加载所有图像时将文本更改为“已加载”。我添加了一个按钮来加载新图像,以确保它也适用于动态加载的图像。

这在 Chrome 中完美运行,但在 Firefox 中,“正在加载...”文本永远不会出现。我不知道为什么会这样。页面开始加载,但并非所有图像都已加载,因此它应该创建文本“正在加载..”,但事实并非如此。然后,当所有图像加载完成后,会出现“正在加载”文本。

我只是不明白为什么会出现一条消息而另一条则不会。特别是因为在创建“正在加载...”文本之前不需要满足任何条件,它应该会自动触发。

jsfiddle 示例| 整页示例

$(document).ready(function() {

    var checkComplete = function() {
        if($('img').filter(function() {return $('img').prop('complete');}).length == $('img').length) {
            $('.status').text('Loaded');
        } else {
            $('.status').text('Loading...');
        }
    };

    $('img').on('load',function() {
        checkComplete();
    });

    $('#button').click(function() {
        $('img.a').attr('src' , 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg');
        $('img.b').attr( 'src' , 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg');
        checkComplete();
    });

    checkComplete();
});
4

2 回答 2

2

您在代码中有几个问题。

首先,checkComplete()函数编写不正确。应该是这样的:

var checkComplete = function() {
    var imgs = $('img');
    if(imgs.filter(function() {return this.complete;}).length == imgs.length) {
        $('.status').text('Loaded');
    } else {
        $('.status').text('Loading...');
    }
};

这里的主要修复是过滤器回调需要引用this.complete,而不是$('img').prop('complete')因为您试图一次过滤单个项目。

其次,您在更改值后依赖两者.complete.load正常工作。.src这显然是它们不能在所有浏览器中正常工作的情况之一。

解决此问题的防弹方法是为新图像创建一个新图像对象,在设置值之前设置 onload 处理程序.src,当两个 onload 处理程序都被触发时,您将知道两个新图像都已加载,您可以替换一旦你在 DOM 中有了新的。

这是一个适用于 FF 的版本:

$(document).ready(function() {

    $('#button').click(function() {
        var imgA = new Image();
        var imgB = new Image();
        imgA.className = "a";
        imgB.className = "b";
        var loaded = 0;
        imgA.onload = imgB.onload = function() {
            ++loaded;
            if (loaded == 2) {
                $("img.a").replaceWith(imgA);
                $("img.b").replaceWith(imgB);
                $('.status').text('Loaded');
            }
        }
        // the part with adding now to the end of the URL here is just for testing purposes to break the cache
        // remove that part for deployment
        var now = new Date().getTime();
        imgA.src = 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg?' + now;
        imgB.src = 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg?' + now;
        $('.status').text('Loading...');
    });
});

工作演示:http: //jsfiddle.net/jfriend00/yy7GX/


如果要保留原始对象,可以仅将新创建的对象用于预加载新图像,然后在预加载后更改 .src,如下所示:

$(document).ready(function() {

    $('#button').click(function() {
        var imgA = new Image();
        var imgB = new Image();
        var loaded = 0;
        imgA.onload = imgB.onload = function() {
            ++loaded;
            if (loaded == 2) {
                $("img.a")[0].src = imgA.src;
                $("img.b")[0].src = imgB.src;
                $('.status').text('Loaded');
            }
        }
        // the part with adding now to the end of the URL here is just for testing purposes to break the cache
        // remove that part for deployment
        var now = new Date().getTime();
        imgA.src = 'http://farm9.staticflickr.com/8545/8675107979_ee12611e6e_o.jpg?' + now;
        imgB.src = 'http://farm9.staticflickr.com/8382/8677371836_651f586c99_o.jpg?' + now;
        $('.status').text('Loading...');
    });
});

此版本的工作演示:http: //jsfiddle.net/jfriend00/ChSQ5/

于 2013-04-24T16:06:39.620 回答
0

来自jQuery API.load方法

与图像一起使用时加载事件的注意事项

开发人员尝试使用 `.load()` 快捷方式解决的一个常见挑战是在图像(或图像集合)完全加载时执行一个函数。应该注意几个已知的警告。这些都是:
  • 它不能始终如一地工作,也不能可靠地跨浏览器
  • 如果图像 src 设置为与以前相同的 src,它不会在 WebKit 中正确触发
  • 它没有正确地冒泡 DOM 树
  • 可以停止对已经存在于浏览器缓存中的图像进行触发
于 2013-04-24T15:14:51.087 回答