不要加载隐藏的图像

时间:2010-09-29 00:51:38

标签: javascript css image http

我的网站上有一堆隐藏的图片。他们的容器DIV有style =“display:none”。根据用户的操作,可以通过javascript显示一些图像。问题是打开页面时我的所有图像都被加载了。我想通过加载最终变得可见的图像来减轻服务器上的压力。我想知道是否有纯CSS方式来做到这一点。这是我目前正在做的两种hacky / complex方式。如您所见,它不是干净的代码。

<div id="hiddenDiv">
   <img src="spacer.gif" />
</div>

.reveal .img {
 background-image: url(flower.png);
}

$('hiddenDiv').addClassName('reveal');

方法2:

<img id="flower" fakeSrc="flower.png" />

function revealImage(id) {
 $('id').writeAttribute(
  'src',
  $('id').readAttribute('fakeSrc')
 );
}

revealImage('flower');

7 个答案:

答案 0 :(得分:32)

浏览器将加载任何设置了src属性的图片,因此您要做的是在标记中使用data-src并使用JavaScript设置src属性你希望它加载。

<img class="hidden" data-src="url/to/image.jpg" />

我创建了这个小插件来解决这个问题:

(function($){
    // Bind the function to global jQuery object.
    $.fn.reveal = function(){
        // Arguments is a variable which is available within all functions
        // and returns an object which holds the arguments passed.
        // It is not really an array, so by calling Array.prototype
        // he is actually casting it into an array.
        var args = Array.prototype.slice.call(arguments);

        // For each elements that matches the selector:
        return this.each(function(){
            // this is the dom element, so encapsulate the element with jQuery.
            var img = $(this),
                src = img.data("src");

            // If there is a data-src attribute, set the attribute
            // src to make load the image and bind an onload event.
            src && img.attr("src", src).load(function(){
                // Call the first argument passed (like fadeIn, slideIn, default is 'show').
                // This piece is like doing img.fadeIn(1000) but in a more dynamic way.
                img[args[0]||"show"].apply(img, args.splice(1));
            });
        });
    }
}(jQuery));

对要加载/显示的图片执行.reveal

$("img.hidden").reveal("fadeIn", 1000);

请参阅test case on jsFiddle

答案 1 :(得分:27)

这是一个jQuery解决方案:

$(function () {
   $("img").not(":visible").each(function () {
       $(this).data("src", this.src);
       this.src = "";
   });

   var reveal = function (selector) {
       var img = $(selector);
       img[0].src = img.data("src");
   }
});

它与您的解决方案类似,不同之处在于它不使用标记中的fakeSrc属性。它会清除src属性以阻止其加载并将其存储在其他位置。一旦准备好显示图像,就可以像使用解决方案一样使用reveal功能。如果你不使用jQuery我很抱歉,但是这个过程应该可以转移到你使用的任何框架(如果有的话)。

注意:必须在窗口触发load事件之后但在加载DOM之后运行此代码。

答案 2 :(得分:2)

部分取决于您的图片必须如何放入代码中。您是否能够将图像显示为&lt; div&gt;的背景,或者您是否需要使用&lt; img&gt;标签?如果你需要&lt; img&gt;标签,您可能会被拧紧,具体取决于所使用的浏览器。有些浏览器足够聪明,可以识别图像是在隐藏对象内部还是在0宽度/高度的对象中,而不是加载它,因为它基本上是不可见的。出于这个原因,许多人会建议将图像放在1x1像素中&lt; span&gt;如果您希望图像预先加载但不可见。

如果您不需要&lt; img&gt;标签,大多数浏览器都不会加载CSS引用的图像,直到有问题的元素变为可见。

请注意,如果没有使用AJAX下载图像,则无法100%确定浏览器无论如何都不会预加载图像。令人难以置信的是,浏览器希望预先加载它可能会在以后使用的任何内容,以“加快”平均加载时间。

答案 3 :(得分:0)

使用CSS将图像放入未使用的类,然后将该类添加到具有javascript的元素将是您最好的选择。如果你根本不使用图像标签,这个解决方案会变得更加明显。

但是,从视角来看,大多数人都有相反的问题,他们想要预先加载图像,以便在被告知显示时立即显示。

答案 4 :(得分:0)

如果你可以依赖脚本,那么有背景图像方法和图像src方法。简而言之,将所有隐藏的图像设置为一个非常小的图像(减少服务器上的压力)或根本不存在的图像(谁在乎?访问者无法看到图像丢失[X]无论如何,div被隐藏)然后用脚本改变它......

<img src="I_do_not_exist.jpg" id="my_image" />
<input type="button" onclick="document.getElementById('my_image').src='I_exist.jpg';" Value="change image" />

<br /><br /><br />

<div id="mydiv" style="width:40px; height:40px; border:2px solid blue"></div>

<input type="button" onclick="document.getElementById('my_div').style.width='455px';document.getElementById('my_div').style.height='75px';document.getElementById('my_div').style.backgroundImage='url(I_exist.jpg)';" Value="change background image" />

我在上面的例子中留下了一个宽度,表明在你要求它加载之前,div图像中没有任何内容。

答案 5 :(得分:0)

If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.

对于纯CSS解决方案,您可以执行以下操作,它还使img框在响应式设计设置中实际上表现得像img框(这是透明png的用途),这在以下情况下特别有用:您的设计使用响应动态调整大小的图像。

<img style="display: none; height: auto; width:100%; background-image: 
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block 
visible-lg-block" src="img/400x186_trans.png" alt="pic 1">

只有在触发绑定到visible-lg-block的媒体查询并且display:none更改为display:block时才会加载图像。透明png用于允许浏览器为&lt; img&gt;设置适当的高度:宽度比率。流体设计中的块(以及背景图像)(高度:自动;宽度:100%)。

1078/501 = ~2.15  (large screen)
400/186  = ~2.15  (small screen)

因此,对于3种不同的视口,您最终会得到以下内容:

<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">

在初始加载期间只会加载默认的媒体视口大小图像,然后根据您的视口加载图像,动态加载图像。

没有javascript!

答案 6 :(得分:0)

很奇怪,对于大多数浏览器已经实现的本地延迟加载,还没有任何答案。

您可以通过在图像中添加loading="lazy"属性来实现。

Addy Osmani撰写了一篇很棒的文章。您可以在此处阅读有关延迟加载的更多信息:https://addyosmani.com/blog/lazy-loading/