读过其他人的问题我想
window.onload=...
会回答我的问题。我试过这个但是它在页面加载的瞬间执行代码(而不是在图像加载之后)。
如果它有任何区别,图像来自CDN并且不是相对的。
有人知道解决方案吗? (我没有使用jQuery)
答案 0 :(得分:27)
以下是现代浏览器的快速入侵:
var imgs = document.images,
len = imgs.length,
counter = 0;
[].forEach.call( imgs, function( img ) {
img.addEventListener( 'load', incrementCounter, false );
} );
function incrementCounter() {
counter++;
if ( counter === len ) {
console.log( 'All images loaded!' );
}
}
加载完所有图像后,您的控制台将显示“所有图像已加载!”。
此代码的作用:
incrementCounter
函数incrementCounter
将递增计数器以跨浏览器的方式使用此代码不会如此很难,它就像这样更清晰。
答案 1 :(得分:18)
想要一线吗?
Promise.all(Array.from(document.images).filter(img => !img.complete).map(img => new Promise(resolve => { img.onload = img.onerror = resolve; }))).then(() => {
console.log('images finished loading');
});
向后兼容,甚至在Firefox 52和Chrome 49(Windows XP时代)中也可以使用。但是,不是在IE11中。
将document.images
替换为例如document.querySelectorAll(...)
如果要缩小图像列表。
为简洁起见,它使用onload
和onerror
。如果img
元素的这些处理程序也设置在其他位置(不太可能,但无论如何),则可能与页面上的其他代码冲突。如果不确定页面是否使用它们并且想确保安全,请用较长的img.onload = img.onerror = resolve;
替换部分img.addEventListener('load', resolve); img.addEventListener('error', resolve);
。
它也不会测试是否所有图像均已成功加载(没有损坏的图像)。如果需要的话,下面是一些更高级的代码:
Promise.all(Array.from(document.images).map(img => {
if (img.complete)
return Promise.resolve(img.naturalHeight !== 0);
return new Promise(resolve => {
img.addEventListener('load', () => resolve(true));
img.addEventListener('error', () => resolve(false));
});
})).then(results => {
if (results.every(res => res))
console.log('all images loaded successfully');
else
console.log('some images failed to load, all finished loading');
});
它一直等到所有图像都加载完毕或加载失败。
如果您想尽早失败,请使用第一个损坏的图像:
Promise.all(Array.from(document.images).map(img => {
if (img.complete)
if (img.naturalHeight !== 0)
return Promise.resolve();
else
return Promise.reject(img);
return new Promise((resolve, reject) => {
img.addEventListener('load', resolve);
img.addEventListener('error', () => reject(img));
});
})).then(() => {
console.log('all images loaded successfully');
}, badImg => {
console.log('some image failed to load, others may still be loading');
console.log('first broken image:', badImg);
});
两个最新的代码块使用naturalHeight
在已加载的图像块中检测损坏的图像。此方法通常可以使用,但有一些drawbacks:当通过CSS content
属性设置图像URL且图像是未指定尺寸的SVG时,据说该方法不起作用。如果是这种情况,则必须重构代码,以便在图像开始加载之前设置事件处理程序。可以通过在HTML中直接指定onload
和onerror
或在JavaScript中创建img
元素来完成。另一种方法是在HTML中将src
设置为data-src
,并在附加处理程序后执行img.src = img.dataset.src
。
答案 2 :(得分:12)
Promise Pattern将以最好的方式解决这个问题我提到了.js一个开源库来解决所有图像加载的问题
function loadImage (src) {
var deferred = when.defer(),
img = document.createElement('img');
img.onload = function () {
deferred.resolve(img);
};
img.onerror = function () {
deferred.reject(new Error('Image not found: ' + src));
};
img.src = src;
// Return only the promise, so that the caller cannot
// resolve, reject, or otherwise muck with the original deferred.
return deferred.promise;
}
function loadImages(srcs) {
// srcs = array of image src urls
// Array to hold deferred for each image being loaded
var deferreds = [];
// Call loadImage for each src, and push the returned deferred
// onto the deferreds array
for(var i = 0, len = srcs.length; i < len; i++) {
deferreds.push(loadImage(srcs[i]));
// NOTE: We could push only the promise, but since this array never
// leaves the loadImages function, it's ok to push the whole
// deferred. No one can gain access to them.
// However, if this array were exposed (e.g. via return value),
// it would be better to push only the promise.
}
// Return a new promise that will resolve only when all the
// promises in deferreds have resolved.
// NOTE: when.all returns only a promise, not a deferred, so
// this is safe to expose to the caller.
return when.all(deferreds);
}
loadImages(imageSrcArray).then(
function gotEm(imageArray) {
doFancyStuffWithImages(imageArray);
return imageArray.length;
},
function doh(err) {
handleError(err);
}
).then(
function shout (count) {
// This will happen after gotEm() and count is the value
// returned by gotEm()
alert('see my new ' + count + ' images?');
}
);
答案 3 :(得分:2)
使用window.onload
将无效,因为一旦页面加载就会触发,但是此加载定义中不包含图像。
对此的一般解决方案是ImagesLoaded jQuery插件。
如果您热衷于完全不使用jQuery,那么至少可以尝试将此插件转换为纯Javascript。在93个重要的代码行和良好的评论中,它不应该是一项艰巨的任务。
答案 4 :(得分:1)
您可以在图像上设置onload事件,该事件可以回调执行处理的函数...关于如何处理所有图像的加载,我不确定以下任何机制是否有效:
有一个函数可以计算调用onload的图像数量,如果这等于页面上的图像总数,那么就进行必要的处理。
答案 5 :(得分:1)
<title>Pre Loading...</title>
</head>
<style type="text/css" media="screen"> html, body{ margin:0;
padding:0; overflow:auto; }
#loading{ position:fixed; width:100%; height:100%; position:absolute; z-index:1; ackground:white url(loader.gif) no-repeat center; }**
</style>
<script> function loaded(){
document.getElementById("loading").style.visibility = "hidden"; }
</script>
<body onload="loaded();"> <div id="loading"></div>
<img id="img" src="avatar8.jpg" title="AVATAR" alt="Picture of Avatar
movie" />
</body>
答案 6 :(得分:1)
游戏稍晚,但我发现以下方法最直接:
function waitForImages () {
let isLoading = true
while (isLoading) {
const loading = [].slice.call(document.images).filter(img => img.complete !== true)
if (!loading.length > 0) {
isLoading = true
return
}
}
}
请注意,这是阻止代码(如果您尝试确保图像像phantomjs一样加载,则非常有用)
答案 7 :(得分:0)
我打算建议同样的事情Baz1nga说。
另外,另一个可能不是万无一失但更容易维护的选项是选择最重要/最大的图像并将onload事件附加到那个。 这里的优点是,如果稍后向页面添加更多图像,则可以更改更少的代码。
答案 8 :(得分:0)
这很棒:
$(function() {
$(window).bind("load", function() {
// code here
});
});