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

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

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


当前回答

浏览器最好使用头部的链接标签。

export function preloadImages (imageSources: string[]): void {
  imageSources
    .forEach(i => {
      const linkEl = document.createElement('link');
      linkEl.setAttribute('rel', 'preload');
      linkEl.setAttribute('href', i);
      linkEl.setAttribute('as', 'image');
      document.head.appendChild(linkEl);
    });
}

其他回答

这是最初的答案,但使用了更现代的ES语法:

let preloadedImages = [];
export function preloadImages(urls) {
    preloadedImages = urls.map(url => {
        let img = new Image();
        img.src = url;
        img.onload = () => console.log(`image url [${url}] has been loaded successfully`);
        
        return img;
    });
}

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岭坝)

.preload-images {
  display: none; 
  width: 0;
  height: 0;
  background: url(img01.jpg),
              url(img02.jpg),
              url(img03.jpg);
}

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

对于感兴趣的人,这里有一些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()在旧的垃圾浏览器中有更好的支持。

这就是我所做的,用承诺:


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