我认为我在这里错过了一条明显的规则,如果澄清它会很棒 -
我正在尝试编写一个图像预加载器,我正在按照此帖子提供的建议: 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,但我不确定它是如何做到的。我有什么不对?
答案 0 :(得分:1)
你所拥有的“可能”会起作用。但是,这不是理想的做事方式,因为它依赖于浏览器和垃圾收集的一些未记录的方面。有关更安全的方法,请参阅here和here。我将尝试解释您的代码正在做什么。
当你这样做时:
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>