【问题标题】:Prevent Bootstrap from preloading all the hidden-* images防止 Bootstrap 预加载所有 hidden-* 图像
【发布时间】:2014-11-05 16:55:40
【问题描述】:

我正在运行 Twitter Bootstrap 3.2。

我的页面对于每个断点都有一个横幅图像。这意味着像这样的代码:

<img class="visible-xs img-responsive" src="headline-768px.jpg">   (128kb)
<img class="visible-sm img-responsive" src="headline-992px.jpg">   (144kb)
<img class="visible-md img-responsive" src="headline-1200px.jpg">  (264kb)
<img class="visible-lg img-responsive" src="headline-2000px.jpg">  (380kb)

拥有 4 张不同图片的主要目的是让移动设备无需下载较大的版本。但无论屏幕大小如何,Bootstrap 都会预加载所有版本,即使它们隐藏在当前断点处也是如此。对于每个观看者来说,这相当于数百个不必要的 kb。

有没有办法解决这个问题?

【问题讨论】:

  • 你应该试试display: none;
  • @MaryMelody Bootstrap 自己的 css 已经显示:无,但它仍然会加载图像。这就是问题。 (我强调图像加载,即使它不显示)。
  • 正如卢卡所说,这与引导无关。在这里阅读一些不同的方法和测试:timkadlec.com/2012/04/media-query-asset-downloading-results

标签: css image twitter-bootstrap responsive-design


【解决方案1】:

问题演示:

Not all browsers react the same,但通常浏览器会从 src 属性加载内容,而不管其他 CSS 规则是否将该元素呈现为不可见。

这是一个基线示例:

<img class="visible-xs img-responsive" src="http://placehold.it/768x150" />
<img class="visible-sm img-responsive" src="http://placehold.it/992x150" />
<img class="visible-md img-responsive" src="http://placehold.it/1200x150"/>
<img class="visible-lg img-responsive" src="http://placehold.it/2000x150"/>

Demo in jsFiddle

每当我刷新页面时,浏览器都会加载所有图像,甚至是最初不可见的图像:

背景图片 + 媒体查询

Simple Responsive Images With CSS Background Images 上的本教程更深入,但基本解决方案是这样的:

创建一个简单的 div:

<div class="responsiveBackgroundImage" id="myImage" ></div>

然后根据屏幕大小插入正确的背景图片:

我们可能希望所有背景图像共享几个基本属性,如下所示:

.responsiveBackgroundImage { 
    width:100%;
    background-size: 100%;
    background-position: 50% 0%;
    background-repeat: no-repeat;
}   

然后在每个分辨率下替换此特定元素的 background-image 属性:

#myImage {background-image: url(http://placehold.it/768x150); }
@media (min-width: 768px)  { #myImage { background-image: url(http://placehold.it/992x150); }}
@media (min-width: 992px)  { #myImage { background-image: url(http://placehold.it/1200x150);}}
@media (min-width: 1200px) { #myImage { background-image: url(http://placehold.it/2000x150);}}

Demo in jsFiddle

用 Javascript 替换图片

由于使用背景图像的限制,您可能决定使用真正的img 元素,然后动态加载图像。在评估解析为 url 的表达式时,您可以执行类似于 angular 对 ng-src 所做的操作,而不是加载元素本身。当浏览器加载每个元素时,它将无法找到src="{{personImageUrl}}" 的文件位置。相反,Angular 将预期的 url 保存为数据属性,然后在适当的时候加载。

首先,获取您的每张图片,并在src 属性前加上data-。现在浏览器不会自动开始实现任何东西,但我们仍然可以使用这些信息。

<img class="visible-xs img-responsive" data-src="http://placehold.it/768x150"/>

然后查询我们最终要加载的所有动态图像。

$dynamicImages = $("[data-src]");

接下来,我们将要捕获窗口调整大小事件,并且在第一个页面加载时,我们将触发一个事件,以便我们可以使用相同的代码。使用这样的函数:

$(window).resize(function() {
    // Code Goes Here
}).resize();

然后检查每个动态图像是否可见。如果是这样,从 data 属性加载图像并将其从数组中删除,这样我们就不必继续检查和加载它了。

$dynamicImages.each(function(index) {
    if ($(this).css('display') !== 'none') {
        this.src = $(this).data('src');
        $dynamicImages.splice(index, 1)
    }
});

Demo in jsFiddle

【讨论】:

  • 你的 JS 解决方案比我的要优雅得多……我会试试的
【解决方案2】:

它不是引导程序,而是浏览器。您应该将背景图片(而不是 &lt;img&gt; 标签)与媒体查询一起使用。

适当的浏览器只会加载与媒体查询匹配的 css 背景图像,但它会加载标记中的所有图像,而不管它们的 css 样式如何

(在&lt;picture&gt;之前的必要痛苦将被广泛支持)

【讨论】:

  • 我最后用 Javascript 做到了:
【解决方案3】:

最后我用 jQuery 做到了。

HTML:

<div id="billboard">
    <a href="#"></a>
</div>

Javascript:

$(document).ready(function(){
        var viewportWidth = $(window).width();
        var adaptiveBillboard = function($showTheRightSizeBilboard){
            if(viewportWidth<641){  
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/ISYNyCw.png">');
            }else if(viewportWidth<721){
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/OQeEwOq.png">');
            }else if(viewportWidth<769){
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/3WqOdgo.png">');
            }else if(viewportWidth<993){
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/KpNKYLq.png">');
            }else if(viewportWidth<1201){
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/F00kkbv.png">');
            }else{
                $('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/FK5ZMoo.png">');
            };
        };
        //try things once on pageload
        $(adaptiveBillboard);
        //try things again on every viewport resize
        $(window).resize(function(){
            viewportWidth = $(window).width();  
            setTimeout(adaptiveBillboard,100);
        });
    });

【讨论】:

【解决方案4】:

我用过(结合 bootstrap hidden-xs):

$dynamicLoadImages = $("img.hidden-xs[data-src]");

$(window).resize(function(index) {
    for (var i = 0; i < $dynamicLoadImages.length; i++) {
        el = $dynamicLoadImages[i];
        if ($(el).css('display') !== 'none') {
            el.src = $(el).data('src');
            $dynamicLoadImages.splice(i, 1);
            i--;
        }
    };
}).resize();

当前的顶级解决方案适用于每个 odd元素,因为splice 方法修改了底层对象,然后跳过下一个元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    相关资源
    最近更新 更多