Fra*_*isc 216 javascript
你能否告诉我,我在下面写的功能是否足以在大多数(如果不是所有)今天常用的浏览器中预装图像?
function preloadImage(url)
{
var img=new Image();
img.src=url;
}
Run Code Online (Sandbox Code Playgroud)
我有一个imageURL数组,我循环并调用每个URL的preloadImage函数.
小智 123
是.这适用于所有主流浏览器.
cli*_*tgh 36
试试这个我认为这更好.
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"
)
Run Code Online (Sandbox Code Playgroud)
资料来源:http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
Ale*_*der 19
在我的例子中,为onload事件的函数添加一个回调是很有用的:
function preloadImage(url, callback)
{
var img=new Image();
img.src=url;
img.onload = callback;
}
Run Code Online (Sandbox Code Playgroud)
然后将它包装为一个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');
});
Run Code Online (Sandbox Code Playgroud)
mpl*_*jan 18
CSS2替代方案:http://www.thecssninja.com/css/even-better-image-preloading-with-css2
body:after {
content: url(img01.jpg) url(img02.jpg) url(img03.jpg);
display: none;
}
Run Code Online (Sandbox Code Playgroud)
CSS3替代方案:https://perishablepress.com/preload-images-css3/ (H/T Linh Dam)
.preload-images {
display: none;
width: 0;
height: 0;
background: url(img01.jpg),
url(img02.jpg),
url(img03.jpg);
}
Run Code Online (Sandbox Code Playgroud)
注意:容器中的图像display:none可能无法预加载.也许可见性:隐藏会更好地工作,但我没有测试过.感谢Marco Del Valle指出这一点
dav*_*ler 16
const preloadImage = src =>
new Promise(r => {
const image = new Image()
image.onload = r
image.onerror = r
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)))
Run Code Online (Sandbox Code Playgroud)
小智 12
您可以将此代码移动到 index.html 以从任何 url 预加载图像
<link rel="preload" href="https://via.placeholder.com/160" as="image">
Run Code Online (Sandbox Code Playgroud)
Dav*_*ave 11
我建议你使用try/catch来防止一些可能的问题:
OOP:
var preloadImage = function (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
Run Code Online (Sandbox Code Playgroud)
标准:
function preloadImage (url) {
try {
var _img = new Image();
_img.src = url;
} catch (e) { }
}
Run Code Online (Sandbox Code Playgroud)
此外,虽然我喜欢DOM,但是旧的愚蠢的浏览器可能会在使用DOM时出现问题,因此完全避免使用IMHO与freedev的贡献相反.Image()在旧的垃圾浏览器中有更好的支持.
fre*_*dev 10
这种方法更精细一些.在这里,您将所有预加载的图像存储在容器中,可能是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;
}
Run Code Online (Sandbox Code Playgroud)
在这里尝试一下,我也添加了一些评论
根据W3C HTML 规范,您现在可以使用 JavaScript 进行预加载,如下所示:
var link = document.createElement("link");
link.rel = "preload";
link.as = "image";
link.href = "https://example.com/image.png";
document.head.appendChild(link);
Run Code Online (Sandbox Code Playgroud)
注意:如果你使用像 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();
Run Code Online (Sandbox Code Playgroud)
您也可以等待所有图像加载完毕。
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);
}
Run Code Online (Sandbox Code Playgroud)
或用于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);
}
Run Code Online (Sandbox Code Playgroud)
这篇文章的大多数答案不再有效 - (至少在 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);
}
Run Code Online (Sandbox Code Playgroud)
用法:
preloadImage("example.com/yourimage.png");
Run Code Online (Sandbox Code Playgroud)
显然<cache>不是“已定义”元素,因此您可以根据需要使用 a <div>。
在你的 CSS 中使用它,而不是应用style属性:
cache {
position: absolute;
z-index: -1000;
opacity: 0;
}
cache image {
position: absolute;
}
Run Code Online (Sandbox Code Playgroud)
如果您对此进行了测试,请发表评论。
笔记:
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"
);
Run Code Online (Sandbox Code Playgroud)
预览:
笔记:
是的,这将起作用,但是浏览器将限制(在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;
}
Run Code Online (Sandbox Code Playgroud)
这是我的方法:
var preloadImages = function (srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
img = new Image;
img.onload = function () {
--remaining;
if (remaining <= 0) {
callback();
}
};
img.src = srcs[i];
imgs.push(img);
}
};
Run Code Online (Sandbox Code Playgroud)