我在下面写的函数是否足以在大多数(如果不是全部的话)当前常用的浏览器中预加载图像?
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函数。
当前回答
这就是我所做的,用承诺:
const listOfimages = [
{
title: "something",
img: "https://www.somewhere.com/assets/images/someimage.jpeg"
},
{
title: "something else",
img: "https://www.somewhere.com/assets/images/someotherimage.jpeg"
}
];
const preload = async () => {
await Promise.all(
listOfimages.map(
(a) =>
new Promise((res) => {
const preloadImage = new Image();
preloadImage.onload = res;
preloadImage.src = a.img;
})
)
);
}
其他回答
是的,这是可行的,但是浏览器会限制(4-8之间)实际的调用,因此不会缓存/预加载所有想要的图像。
更好的方法是在使用图像之前调用onload,如下所示:
function (imageUrls, index) {
var img = new Image();
img.onload = function () {
console.log('isCached: ' + isCached(imageUrls[index]));
*DoSomething..*
img.src = imageUrls[index]
}
function isCached(imgUrl) {
var img = new Image();
img.src = imgUrl;
return img.complete || (img .width + img .height) > 0;
}
是的。这应该可以在所有主流浏览器上运行。
对于感兴趣的人,这里有一些OP提供的代码的替代方案。
预加载图像()
函数现在返回
function preloadImage = function(url){
const img = new Image();
img.src = url;
return img
}
v1:通过将图像作为参数传递给preloadImages()来预加载
返回函数返回的Image类型对象数组。有助于检查预紧状态。
js小提琴
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages() {
const images = []
for (var i = 0; i < arguments.length; i++) {
images[i] = preloadImage(arguments[i])
}
return images
}
//-- usage --//
const images = preloadImages(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
)
v2:通过将图像作为数组传递给preloadImages()来预加载
不类型安全 用Image类型对象覆盖提供的数组。返回函数返回的Image类型对象数组。有助于检查预紧状态。
js小提琴
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages(images) {
for (var i = 0; i < images.length; i++) {
images[i] = preloadImage(images[i])
}
return images
}
//-- usage --//
let arr = [
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
]
const images = preloadImages(arr)
console.dir(images)
v3:通过传递数组和/或参数来预加载preloadImages()
类型安全。返回函数返回的Image类型对象数组。有助于检查预紧状态。
js小提琴
function preloadImage(url){
const img = new Image();
img.src = url;
return img
}
function preloadImages() {
const images = []
let c = 0
for (var i = 0; i < arguments.length; i++) {
if (Array.isArray(arguments[i])) {
for(var arr = 0; arr < arguments[i].length; arr++) {
if(typeof arguments[i][arr] == 'string') {
images[c] = preloadImage(arguments[i][arr])
c++
}
}
}
else if(typeof arguments[i] == 'string') {
images[c] = preloadImage(arguments[i])
c++
}
}
return images
}
//-- usage --//
var arr = [
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg"
]
const images = preloadImages(
arr,
"http://domain.tld/gallery/image-003.jpg",
"http://domain.tld/gallery/image-004.jpg",
[
"http://domain.tld/gallery/image-005.jpg",
"http://domain.tld/gallery/image-006.jpg"
]
)
console.dir(images)
灵感来源于:http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
我建议你使用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的贡献相反,完全避免使用DOM。Image()在旧的垃圾浏览器中有更好的支持。
ECMAScript 2017兼容浏览器的解决方案
注意:如果你使用的是像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。所有这些都是并行加载的。
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);
}
更多关于承诺。
更多关于“异步”函数。
更多关于解构赋值的内容。
更多关于ECMAScript 2015。
更多关于ECMAScript 2017。