0

我在仅在一个方面适应 jQuery 图像预加载脚本时遇到了麻烦:我不知道如何确保我的图像按图像数组的顺序加载/显示。

目前,每次我重新加载页面时,图像都会以不同的顺序显示。(除了图像顺序之外的所有东西都可以正常工作。)

谁能帮我解决这个问题?

相关代码:

    (function($) {
        var imgList = [];
        $.extend({
            preload: function(imgArr, option) {
                var setting = $.extend({
                    init: function(loaded, total) {},
                    loaded: function(img, loaded, total, bild) {},
                    loaded_all: function(loaded, total) {}
                }, option);
                var total = imgArr.length;
                var loaded = 0;

                setting.init(0, total);
                for (var i = 0; i < total; i++) {
                    imgList[i] = ($("<img />")
                        .attr("src", imgArr[i])
                        .load(function() {
                            loaded++;
                            setting.loaded(this, loaded, total, this.src);
                            if(loaded == total) {
                                setting.loaded_all(loaded, total);
                            }
                        })
                    );
                }
           }
        });
    })(jQuery);

    $(document).ready(function() {
        $(function() {
            $.preload([
                "image1.jpg",
                "image2.jpg",
                "image3.jpg"
            ], {
                init: function(loaded, total) {
                    var z = 0;
                    while (z < total) {
                        z++;
                        $("section nav").append('<img id="e'+z+'" src="all/blank.png" alt=""/>');
                    }
                },
                loaded: function(img, loaded, total, bild) {
                    $("#e"+loaded).prop("src",bild);
                },
                loaded_all: function(loaded, total) {
                    //all done!
                }
            });
        });
    });

更新:

最后,我用一个完全不同的、更短的脚本解决了这个问题,我从头开始编写。它开始向我的图像容器添加尽可能多(非常小的)虚拟图像作为占位符,因为数组包含真实图像,并且仅在前一个图像完成后加载每个图像:

imgs = new Array("number1.png","number2.png","number3.png");

for (i=0; i<imgs.length; i++) {
  $("section nav").append('<img id="e'+i+'" src="blank.png" alt=""/>');
}

fin(0);

function fin (n) {
  $('#e'+n).attr('onload', 'fin('+n+')');
  $("#e"+n).attr("src", imgs[n]).load( function() {
    fin ((n+1));
  });
}
4

3 回答 3

1

问题是您将加载的 img 附加到当前加载的图像数量的位置,即图像按加载顺序放置。

您实际上希望它们在以下时间订购var i

for (var i = 0; i < total; i++) {
    imgList[i] = ($("<img />")
        .attr("src", imgArr[i])
        .load(function() {
            loaded++;
            setting.loaded(this, i, total, this.src);  // i instead of loaded
            if(loaded == total) {
                setting.loaded_all(loaded, total);
            }
        })
    );
}

但这不起作用,因为i将与total加载图像时相同,因此所有图像都将转到 position total。不是你想要的!

所以我们需要将它包装在一个自调用匿名函数中以访问正确的i值:

for (var i = 0; i < total; i++) {

    // wrap in function to get access to the right i

    (function(img) {
        imgList[img] = ($("<img />")
            .attr("src", imgArr[img])
            .load(function() {
                loaded++;
                setting.loaded(this, img, total, this.src);  // img instead of i
                if(loaded == total) {
                    setting.loaded_all(loaded, total);
                }
            })
        );
    })(i);
}

用这个替换你的 for 循环,它应该可以工作。

于 2012-06-05T17:02:25.803 回答
0

除非您将每个图像的下载延迟到上一个图像完成(这将是一个坏主意),否则您无法保证它们将以什么顺序下载。

浏览器通常会并行下载多个图像,以优化吞吐量。将其与不可预测的下载速度和不同的文件大小相结合,文件将以几乎任何顺序完成。

如果是你想要的视觉效果,那你就得单独解决了。

于 2012-06-05T16:55:40.770 回答
0

您的loaded回调将永远不会按顺序调用,因为图像是异步加载的。但是,您应该loaded_all改为传递原始数组。这样您的处理程序就可以按顺序处理图像。

if(loaded == total) {
    setting.loaded_all(imgArray);
}
于 2012-06-05T17:00:31.520 回答