Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript预加载图像_Javascript - Fatal编程技术网

使用JavaScript预加载图像

使用JavaScript预加载图像,javascript,Javascript,我在下面编写的函数是否足以在大多数(如果不是全部)浏览器中预加载图像 function preloadImage(url) { var img=new Image(); img.src=url; } 我有一个图像URL数组,我循环并为每个URL调用preload image函数。是。这应该适用于所有主要浏览器 是的。这应该适用于所有主要浏览器 CSS2备选方案: CSS3备选方案: (H/T林坝) 注意:display:none容器中的图像可能无法预加载。 也许可见性:hidd

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

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

我有一个图像URL数组,我循环并为每个URL调用
preload image
函数。

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

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

CSS2备选方案:

CSS3备选方案: (H/T林坝)

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

CSS2备选方案:

CSS3备选方案: (H/T林坝)

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

这种方法更为复杂。在这里,您将所有预加载的图像存储在一个容器中,可能是一个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;
}

,我还添加了一些评论

这种方法更为详细。在这里,您将所有预加载的图像存储在一个容器中,可能是一个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来防止一些可能的问题:

面向对象:

标准:

    function preloadImage (url) {
        try {
            var _img = new Image();
            _img.src = url;
        } catch (e) { }
    }

另外,虽然我喜欢DOM,但旧的愚蠢的浏览器可能会在使用DOM时遇到问题,所以与freedev的贡献相反,完全避免使用DOM。Image()在旧的垃圾浏览器中有更好的支持。

我建议您使用try/catch来防止一些可能的问题:

面向对象:

标准:

    function preloadImage (url) {
        try {
            var _img = new Image();
            _img.src = url;
        } catch (e) { }
    }

另外,虽然我喜欢DOM,但旧的愚蠢的浏览器可能会在使用DOM时遇到问题,所以与freedev的贡献相反,完全避免使用DOM。Image()在旧的垃圾浏览器中有更好的支持。

试试这个,我觉得这样更好

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"
)
var-images=[];
函数预加载(){
for(var i=0;i

来源:

试试这个,我觉得这个更好

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"
)
var-images=[];
函数预加载(){
for(var i=0;i

来源:

是的,这将起作用,但是浏览器将限制实际调用(在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;
}

是的,这将起作用,但是浏览器将限制实际调用(在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;
}

在我的例子中,为
onload
事件向函数添加回调非常有用:

function preloadImage(url, callback)
{
    var img=new Image();
    img.src=url;
    img.onload = callback;
}
然后将其包装为一个URL数组,以便在所有操作完成时使用回调预加载图像:


在我的例子中,为
onload
事件向函数添加回调非常有用:

function preloadImage(url, callback)
{
    var img=new Image();
    img.src=url;
    img.onload = callback;
}
然后将其包装为一个URL数组,以便在所有操作完成时使用回调预加载图像:

我的做法如下:

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);
    }
};
var preload images=函数(srcs、imgs、回调){
var-img;
剩余var=srcs.length;
对于(变量i=0;i
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);
    }
};
var preload images=函数(srcs、imgs、回调){
var-img;
剩余var=srcs.length;
对于(变量i=0;i如果(剩余我可以确认问题中的方法足以触发图像下载和缓存(除非您已禁止浏览器通过您的响应头进行此操作),至少:

  • 铬74
  • 狩猎12
  • 火狐66
  • 边缘17
为了测试这一点,我制作了一个带有多个端点的小型网络应用程序,每个端点在提供一张小猫的照片之前都会休眠10秒。然后我添加了两个网页,其中一个网页包含一个
标签,其中每只小猫都使用问题中的
preload image
功能预加载,另一个网页包含所有的kit使用
标记在页面上单击

在上面的所有浏览器中,我发现如果我先访问预加载程序页面,等待一段时间,然后转到带有
标记的页面,我的小猫会立即呈现。这表明预加载程序在所有测试的浏览器中都成功地将小猫加载到缓存中

您可以查看或试用我用于测试此功能的应用程序


特别要注意的是,即使循环的图像数量超过了浏览器一次愿意发出的并行请求数量(与建议相反),这种技术也适用于上述浏览器。图像预加载的速率当然会受到浏览器愿意发出的并行请求数量的限制发送,但它最终会请求您调用的每个图像URL
preload image()

我可以确认问题中的方法足以触发下载和缓存图像(除非您已通过响应标题禁止浏览器这样做
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);
}
<link rel="preload" href="https://via.placeholder.com/160" as="image">
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)))
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);
    });
}