使用 JavaScript 预加载图像

IT技术 javascript
2021-01-20 16:46:18

我在下面编写的函数是否足以在当今常用的大多数(如果不是全部)浏览器中预加载图像?

function preloadImage(url)
{
    var img=new Image();
    img.src=url;
}

我有一组图像 URL,我循环遍历preloadImage这些 URL为每个 URL调用函数。

6个回答

是的。这应该适用于所有主要浏览器。

主持人注意:请停止将此标记为“不是答案”。事实上,这是对所问问题的直接回答。如果你认为答案是错误的,或者没有足够的证据支持,那么就投反对票
2021-04-01 16:46:18

对于任何感兴趣的人,这里有一些 OP 提供的代码的替代方法。

preloadImage()

函数现在返回

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:预压通过使任一阵列(一个或多个)和/或参数(s到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/

你能解释一下为什么这更好吗?
2021-03-18 16:46:18
@BeNice 我认为您误解了,加载图像是异步的,因此您必须处理onload状态或者您只是在内存中实例化图像。
2021-03-29 16:46:18
如果您使用此解决方案,请不要忘记 i 变量的 var 语句。否则它将被全局设置,这可能会导致很难解决的错误(除非你知道你忘记了 var 语句。for (var i = 0.....
2021-03-29 16:46:18
@Mohammer 对此表示感谢,我只是从我提供的链接中复制了代码。我现在将编辑代码以添加var
2021-04-07 16:46:18
没有onload任何图像的处理程序
2021-04-09 16:46:18

就我而言,为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');
});

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; 
}

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);
}

注意:容器中的图像display:none可能不会预加载。也许可见性:隐藏会更好,但我还没有测试过。感谢 Marco Del Valle 指出这一点

这种方法只对我有用display: none我 (1) 没有使用,(2) 没有使用width/height: 0,(3) putno-repeat和一个位置,这样图像就会在外面(-<width>px -<height>px会让你到那里,所以如果你的图像都是 100px高度或更小,您可以使用0 -100px,换句话说url(...) no-repeat 0 -100px
2021-03-10 16:46:18
谢谢 mplungjan。虽然它对我的这种特殊情况没有帮助,但很高兴知道。
2021-03-25 16:46:18
我不相信这些将适用于所有浏览器。我知道在 Chrome 上的图像在可见之前不会加载。将需要删除显示:无;而是尝试定位它们,使它们无法被看到。如果需要,可以在所有内容加载后使用 JS 隐藏。
2021-03-27 16:46:18
元素中的背景图像display: none不会预加载。
2021-03-30 16:46:18
我说这会减慢页面的加载速度是否正确,因为需要在页面启动加载事件之前下载这些图像?
2021-04-02 16:46:18

您可以将此代码移动到 index.html 以从任何 url 预加载图像

<link rel="preload" href="https://via.placeholder.com/160" as="image">
这个答案没有得到足够的关注,因为它是实践中最不麻烦的方法之一。
2021-03-22 16:46:18
同意。这对于在轮播中预加载图像也非常有效。感谢发布!
2021-04-08 16:46:18