134

我有一个隐藏的联系表格,点击一个按钮即可部署。它的字段设置为 CSS 背景图像,并且它们总是比已切换的 div 稍晚出现。

我在本节中使用了这个片段<head>,但没有运气(在我清除缓存之后):

<script>
$(document).ready(function() {
        pic = new Image();
        pic2 = new Image();
        pic3 = new Image();
        pic.src="<?php bloginfo('template_directory'); ?>/images/inputs/input1.png";
        pic2.src="<?php bloginfo('template_directory'); ?>/images/inputs/input2.png";
        pic3.src="<?php bloginfo('template_directory'); ?>/images/inputs/input3.png";
});
</script>

我正在使用 jQuery 作为我的库,如果我也可以使用它来解决这个问题,那就太棒了。

谢谢你的想法。

4

13 回答 13

296

仅使用 CSS 预加载图像

在下面的代码中,我随机选择body元素,因为它是唯一保证存在于页面上的元素之一。

为了使“技巧”发挥作用,我们将使用content允许设置加载多个URL 的属性,但如图所示,::after伪元素保持隐藏,因此不会呈现图像:

body::after{
   position:absolute; width:0; height:0; overflow:hidden; z-index:-1; // hide images
   content:url(img1.png) url(img2.png) url(img3.gif) url(img4.jpg);   // load images
}

在此处输入图像描述

演示


最好使用sprite 图像来减少 http 请求......(如果有许多相对较小的图像)并确保图像托管在使用HTTP2的位置。

于 2013-01-17T23:47:14.187 回答
42

使用 HTML <link> 标签预加载图片

我相信这个问题的大多数访问者都在寻找“如何在页面渲染开始之前预加载图像?”的答案。这个问题的最佳解决方案是使用<link>标签,因为<link>标签能够阻止页面的进一步呈现。见抢先

rel当前文档和链接文档之间的关系)属性的这两个值选项与问题最相关:

  • prefetch : 在页面渲染时加载给定的资源
  • preload : 在页面渲染开始之前加载给定的资源

因此,如果您想在标签的渲染过程开始之前加载资源(在这种情况下是图像),请使用:<body>

<link rel="preload" as="image" href="IMAGE_URL">

如果您想在<body>渲染时加载资源,但您打算稍后动态使用它并且不想在加载时间上打扰用户,请使用:

<link rel="prefetch" href="RESOURCE_URL">
于 2017-01-22T07:43:13.157 回答
33

我可以确认我的原始代码似乎有效。我随意地坚持使用错误路径的图像。

这是一个测试: http: //paragraphe.org/slidetoggletest/test.html

<script>
    var pic = new Image();
    var pic2 = new Image();
    var pic3 = new Image();
    pic.src="images/inputs/input1.png";
    pic2.src="images/inputs/input2.png";
    pic3.src="images/inputs/input3.png";
</script>
于 2009-09-03T17:52:57.590 回答
14

http://css-tricks.com/snippets/css/css-only-image-preloading/

技术#1

将图像加载到元素的常规状态,仅将其与背景位置移开。然后移动背景位置以在悬停时显示它。

#grass { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background-position: bottom left; }

技术#2

如果有问题的元素已经应用了背景图像并且您需要更改该图像,则上述方法将不起作用。通常你会在这里选择一个精灵(一个组合的背景图像),然后移动背景位置。但如果这不可能,试试这个。将背景图像应用到另一个已在使用但没有背景图像的页面元素。

#random-unsuspecting-element { background: url(images/grass.png) no-repeat -9999px -9999px; }
#grass:hover { background: url(images/grass.png) no-repeat; }
于 2011-01-06T12:50:08.583 回答
10

试试这个:

var c=new Image("Path to the background image");
c.onload=function(){
   //render the form
}

使用此代码,您可以预加载背景图像并在加载时呈现表单

于 2009-09-03T12:51:35.153 回答
7

对于使用 CSS 设置的预加载背景图像,我想出的最有效的答案是我发现一些代码的修改版本不起作用:

$(':hidden').each(function() {
  var backgroundImage = $(this).css("background-image");
  if (backgroundImage != 'none') {
    tempImage = new Image();
    tempImage.src = backgroundImage;
  }
});

这样做的巨大好处是,当您将来引入新的背景图像时,您不需要更新它,它会找到新的并预加载它们!

于 2012-10-19T04:07:32.703 回答
5

如果您在站点的其他任何地方重复使用这些 bg 图像来进行表单输入,您可能想要使用图像精灵。这样您就可以集中管理您的图像(而不是拥有 pic1、pic2、pic3 等......)。

对于客户端来说,Sprite 通常更快,因为它们只从服务器请求一个(尽管稍微大一点)文件而不是多个文件。有关更多好处,请参见 SO 文章:

CSS 图像精灵

再说一次,如果您只是将这些用于一个表单并且您真的只想在用户请求联系表单时加载它们,这可能根本没有帮助......不过可能有意义。

http://www.alistapart.com/articles/sprites

于 2009-09-03T21:26:43.333 回答
1

如何在隐藏的地方加载该背景图像。这样,它会在页面打开时加载,并且一旦使用 ajax 创建表单就不会花费任何时间:

body {
background: #ffffff url('img_tree.png') no-repeat -100px -100px;
}
于 2009-09-03T12:52:58.560 回答
1

唯一的方法是对图像进行 Base64 编码并将其放在 HTML 代码中,这样它就不需要联系服务器来下载图像。

将从 url 对图像进行编码,因此您可以复制图像文件代码并将其插入到您的页面中,就像这样...

body {
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...);
}
于 2011-09-25T06:00:35.317 回答
1

您可以使用这个 jQuery 插件waitForImage或者您可以将图像放入隐藏的 div 或(宽度:0 和高度:0)并在图像上使用 onload 事件。

如果您只有 2-3 张图像,您可以绑定事件并在链中触发它们,因此在每个图像之后您都可以执行一些代码。

于 2012-03-14T23:05:47.860 回答
1

当无法修改 CSS 代码并使用 CSS 规则:before:after伪元素预加载图像时,可以使用另一种 JavaScript 代码遍历加载样式表的 CSS 规则的方法。为了使其工作脚本应该包含在 HTML 中的样式表之后,例如,在结束body标记之前或样式表之后。

getUrls() {
    const urlRegExp = /url\(('|")?([^'"()]+)('|")\)?/;

    let urls = [];
    for (let i = 0; i < document.styleSheets.length; i++) {
        let cssRules = document.styleSheets[i].cssRules;
        for (let j = 0; j < cssRules.length; j++) {
            let cssRule = cssRules[j];
            if (!cssRule.selectorText) {
                continue;
            }

            for (let k = 0; k < cssRule.style.length; k++) {
                let property = cssRule.style[k],
                    urlMatch = cssRule.style[property].match(urlRegExp);
                if (urlMatch !== null) {
                    urls.push(urlMatch[2]);
                }
            }
        }
    }
    return urls;
}

preloadImages() {
    return new Promise(resolve => {
        let urls = getUrls(),
            loadedCount = 0;

        const onImageLoad = () => {
            loadedCount++;
            if (urls.length === loadedCount) {
                resolve();
            }
        };

        for (var i = 0; i < urls.length; i++) {
            let image = new Image();
            image.src = urls[i];
            image.onload = onImageLoad;
        }
    });
}

document.addEventListener('DOMContentLoaded', () => {
    preloadImages().then(() => {
        // CSS images are loaded here
    });
});
于 2016-10-28T19:19:43.603 回答
0

如果页面元素及其背景图像已经在 DOM 中(即您没有动态创建/更改它们),那么它们的背景图像将已经被加载。那时,您可能想查看压缩方法 :)

于 2009-09-03T12:45:02.943 回答
0

我还想添加小通知。

如果您没有在网络选项卡的开发控制台设置中禁用缓存,则回答“仅使用 CSS 预加载图像”非常有效。否则它将双重加载图像。

在此处输入图像描述

于 2021-04-17T00:02:30.560 回答