为什么这个“加载消息”脚本在FF中不起作用?(javascript)

时间:2013-04-24 15:02:14

标签: javascript jquery image loading

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

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

我只是不明白为什么会出现一条消息而另一条消息不会出现。特别是因为在创建“正在加载...”文本之前没有必须满足的资格,它应该只是自动触发。

jsfiddle Example | Full Page Example

$(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();
});

2 个答案:

答案 0 :(得分: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正常工作。这显然是在所有浏览器中无法正常工作的情况之一。

解决这个问题的防弹方法是为新图像创建一个新的图像对象,在设置.src值之前设置onload处理程序,当两个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/

答案 1 :(得分:0)

来自jQuery API .load method

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

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