我写的以下函数足以在今天常用的大多数浏览器中预加载图片吗?
function preloadImage(url)
{
var img=new Image();
img.src=url;
}
我有一个图片URL数组,会对每个URL调用preloadImage
函数。
我写的以下函数足以在今天常用的大多数浏览器中预加载图片吗?
function preloadImage(url)
{
var img=new Image();
img.src=url;
}
我有一个图片URL数组,会对每个URL调用preloadImage
函数。
是的。这适用于所有主流浏览器。
尝试这个,我认为这更好。
var images = [];
function preload() {
for (var i = 0; i < arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
}
}
//-- usage --//
preload(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
)
来源: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
onload
处理程序。 - Benny Schmidtfor (var i = 0.....
- Mohammervar
。 - clintgh您可以将此代码移动到 index.html 中,以从任何 URL 预加载图像。
<link rel="preload" href="https://via.placeholder.com/160" as="image">
在我的情况下,为您的函数添加一个 onload
事件回调函数是有用的:
function preloadImage(url, callback)
{
var img=new Image();
img.src=url;
img.onload = callback;
}
如果要预加载图像URL的数组并在所有操作完成后执行回调,则可以使用以下代码进行封装: https://jsfiddle.net/4r0Luoy7/
function preloadImages(urls, allImagesLoadedCallback){
var loadedCounter = 0;
var toBeLoadedNumber = urls.length;
urls.forEach(function(url){
preloadImage(url, function(){
loadedCounter++;
console.log('Number of loaded images: ' + loadedCounter);
if(loadedCounter == toBeLoadedNumber){
allImagesLoadedCallback();
}
});
});
function preloadImage(url, anImageLoadedCallback){
var img = new Image();
img.onload = anImageLoadedCallback;
img.src = url;
}
}
// Let's call it:
preloadImages([
'//upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg',
'//www.csee.umbc.edu/wp-content/uploads/2011/08/www.jpg'
], function(){
console.log('All images were loaded');
});
const preloadImage = src =>
new Promise((resolve, reject) => {
const image = new Image()
image.onload = resolve
image.onerror = reject
image.src = src
})
// Preload an image
await preloadImage('https://picsum.photos/100/100')
// Preload a bunch of images in parallel
await Promise.all(images.map(x => preloadImage(x.src)))
body:after {
content: url(img01.jpg) url(img02.jpg) url(img03.jpg);
display: none;
}
.preload-images {
display: none;
width: 0;
height: 0;
background: url(img01.jpg),
url(img02.jpg),
url(img03.jpg);
}
注意:在带有display:none
样式的容器中的图像可能无法预加载。
也许使用visibility:hidden
样式效果更好,但我没有测试过。感谢Marco Del Valle指出这一点。
display: none
属性的元素中的背景图像将不会预加载。 - M -display: none
,(2)也没有使用width/height: 0
,(3)我使用了no-repeat
和一个使图像位于外部的位置(-<width>px -<height>px
将把它带到那里,所以如果您的图像高度都小于100px,您可以使用0 -100px
,换句话说,url(...) no-repeat 0 -100px
)。 - Alexis Wilke这篇帖子中的大多数答案已经不再起作用了(至少在Firefox上)。
以下是我的解决方案:
var cache = document.createElement("CACHE");
cache.style = "position:absolute;z-index:-1000;opacity:0;";
document.body.appendChild(cache);
function preloadImage(url) {
var img = new Image();
img.src = url;
img.style = "position:absolute";
cache.appendChild(img);
}
使用方法:
preloadImage("example.com/yourimage.png");
<cache>
不是一个“定义”元素,如果需要,可以使用<div>
。在CSS中使用以下内容,而不是应用style
属性:
cache {
position: absolute;
z-index: -1000;
opacity: 0;
}
cache image {
position: absolute;
}
如果你已经测试过,请留下评论。
注:
display: none;
应用于缓存 - 这样不会加载图像。position: absolute
设置为图像是必要的,因为图像元素最终会超出视口范围 - 导致它们无法加载,并影响性能。虽然上面的解决方案可以工作,但我做了一些小更新以使其结构更好:
(现在也接受一个函数中的多个图像)
var cache = document.createElement("CACHE");
document.body.appendChild(cache);
function preloadImage() {
for (var i=0; i<arguments.length; i++) {
var img = new Image();
img.src = arguments[i];
var parent = arguments[i].split("/")[1]; // Set to index of folder name
if ($(`cache #${parent}`).length == 0) {
var ele = document.createElement("DIV");
ele.id = parent;
cache.appendChild(ele);
}
$(`cache #${parent}`)[0].appendChild(img);
console.log(parent);
}
}
preloadImage(
"assets/office/58.png",
"assets/leftbutton/124.png",
"assets/leftbutton/125.png",
"assets/leftbutton/130.png",
"assets/leftbutton/122.png",
"assets/leftbutton/124.png"
);
预览:
注意事项:
这种方法稍微复杂一些。在这里,您将所有预加载的图像存储在一个容器中,可能是一个div。之后,您可以显示这些图片或将其移动到DOM中的正确位置。
function preloadImg(containerId, imgUrl, imageId) {
var i = document.createElement('img'); // or new Image()
i.id = imageId;
i.onload = function() {
var container = document.getElementById(containerId);
container.appendChild(this);
};
i.src = imgUrl;
}
在这里试一下,我也添加了几个注释
我建议你使用try/catch来防止一些可能出现的问题:
面向对象编程(OOP):
var preloadImage = function (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
标准:
function preloadImage (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
此外,虽然我喜欢DOM,但古老而愚蠢的浏览器可能会出现使用DOM的问题,因此我认为最好完全避免使用它,与freedev的贡献相反。在旧垃圾浏览器中,Image()有更好的支持。
注意:如果您使用类似Babel的转译器,此方法同样适用。
'use strict';
function imageLoaded(src, alt = '') {
return new Promise(function(resolve) {
const image = document.createElement('img');
image.setAttribute('alt', alt);
image.setAttribute('src', src);
image.addEventListener('load', function() {
resolve(image);
});
});
}
async function runExample() {
console.log("Fetching my cat's image...");
const myCat = await imageLoaded('https://placekitten.com/500');
console.log("My cat's image is ready! Now is the time to load my dog's image...");
const myDog = await imageLoaded('https://placedog.net/500');
console.log('Whoa! This is now the time to enable my galery.');
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
runExample();
async function runExample() {
const [myCat, myDog] = [
await imageLoaded('https://placekitten.com/500'),
await imageLoaded('https://placedog.net/500')
];
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
或者使用 Promise.all
并行加载它们。
async function runExample() {
const [myCat, myDog] = await Promise.all([
imageLoaded('https://placekitten.com/500'),
imageLoaded('https://placedog.net/500')
]);
document.body.appendChild(myCat);
document.body.appendChild(myDog);
}
img
对象的引用,例如在父级范围的数组中。 - Tamlyn(new Image()).src = url;
- e382df99a7950919789725ceeec126new Image().src = url;
- Daniel X Moore