将多个图像传递给Image()对象时感到困惑

时间:2013-11-17 15:24:43

标签: javascript html dom

我认为我在这里错过了一条明显的规则,如果澄清它会很棒 -

我正在尝试编写一个图像预加载器,我正在按照此帖子提供的建议: Preloading images in Javascript? Without jQuery

我可以看到它如何运作直到:

    for(var i = 0; i < imageList.length; i++ ) {
        var imageObject = new Image();
        imageObject.src = imageList[i]; }

我一直认为这只会在每次迭代时更改/覆盖src属性,将imageObject.src保留为循环结束时列表中的最后一个图像,但显然该函数用于使用多个图像。

所以我假设它留下了包含图像数组的imageObject,但我不确定它是如何做到的。我有什么不对?

2 个答案:

答案 0 :(得分:1)

你所拥有的“可能”会起作用。但是,这不是理想的做事方式,因为它依赖于浏览器和垃圾收集的一些未记录的方面。有关更安全的方法,请参阅herehere。我将尝试解释您的代码正在做什么。

当你这样做时:

   var imageObject = new Image();

它正在创建一个新的DOM图像对象,并在变量imageObject中放置对该对象的引用。

当你这样做时:

    imageObject.src = imageList[i];

它正在分配该新图像对象的.src属性。这不会覆盖前一个图像对象的.src属性。

但是,因为以前的图像对象没有存储在任何地方,并且没有其他javascript对它们有任何引用,所以它们可供浏览器进行垃圾收集,并且可以随时自由删除它们。要使用它来实现可靠的缓存,您希望浏览器不会取消正在加载图像的正在进行的网络操作,并且您希望它们仍然可以进入浏览器缓存以便预加载。

imageObject存储在数组中会更安全,因为我已经指出过其他解决方案。这样可以防止它们被垃圾收集,因此不会有图像加载被取消的风险。

例如,这样做会更安全:

var imgs = [];
for (var i = 0; i < imageList.length; i++ ) {
    var imageObject = new Image();
    imageObject.src = imageList[i]; 
    imgs.push(imageObject);
}

前面两个对其他解决方案的引用做了类似的事情,但是将它打包成一个函数,并且还能够在所有图像完成预加载时通知你。

答案 1 :(得分:1)

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        var imageList = new Array("dummyImg1.jpg", "dummyImg2.jpg");
        var imagePlaceholder = new Array(imageList.length);
        function waitImagesLoaded() {
            var allImagesLoaded = true;
            for (var i = 0; i < imageList.length && allImagesLoaded; i++) {
                allImagesLoaded &= imagePlaceholder[i].complete;
            }
            if (allImagesLoaded) {
                for (var i = 0; i < imageList.length; i++) {
                    var imgElemIdToReplace = "img" + String(i + 1);
                    replaceElem(imagePlaceholder[i], document.getElementById(imgElemIdToReplace));
                }
            } else {
                window.setTimeout(waitImagesLoaded, 500);
            }
        }
        function replaceElem(substituteElem, elemToReplace) {
            var parentNode = elemToReplace.parentNode;
            parentNode.replaceChild(substituteElem, elemToReplace);
        }
    </script>
</head>
<body>
    <img id="img1" src="" alt="">
    <img id="img2" src="" alt="">
    <script type = "text/javascript">
       for (var i = 0; i < imageList.length; i++) {
            var imageObject = new Image();
            imageObject.src = imageList[i];
            imagePlaceholder[i] = imageObject;
        }
        window.setTimeout(waitImagesLoaded, 500);
    </script>
</body>
</html>