有条件地为响应式设计加载图像

Posted

技术标签:

【中文标题】有条件地为响应式设计加载图像【英文标题】:conditionally load images for responsive designs 【发布时间】:2013-06-19 10:00:42 【问题描述】:

我正在为现有网站改造自适应布局。基本上在 500 像素时,网站会更改为 100% 宽度的移动样式布局。通常我会使用 ems,但正如我所说,我正在改装。

我知道如何有条件地加载js和css,但是html和图片呢?

在网站的主页上有一个充满屏幕的大图像,我的小屏幕布局不需要它,所以如果浏览器宽度超过 500 像素,我希望它加载。问题是我无法将<img src="..." /> 等存储在 js 中,因为它是用 php 动态加载的。客户端通过wordpress admin控制图片。

任何想法将不胜感激。谢谢

【问题讨论】:

【参考方案1】:

这个问题很老,但我有同样的问题,并想为可能感兴趣的其他人编写我的解决方案。

客户端仅使用 Angular js

在客户端,您“发现”应该加载的资源“类型”。例如,在主应用控制器中:

$scope.type = (screen.width > 500) ? 'desktop' : 'mobile';
// or window.navigator

然后在要有条件地显示的内容中,添加变量

<img src="images/type/foo.jpg">

注意:您放置控制器的位置很重要。如果在&lt;/body&gt;标签之前,浏览器会在angular展开变量之前发出请求。如果它在'`中,则在浏览器发出请求之前扩展变量

仅服务器端 (PHP)

您可以使用$_SERVER['HTTP_USER_AGENT']; 来检测它是否是移动设备并采取相应措施。

显然用户代理可以被欺骗,但由于唯一的区别是图像大小,最糟糕的情况是您在大屏幕上提供小图像,反之亦然。

例如:

$useragent=$_SERVER['HTTP_USER_AGENT'];

if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4))) 
  $type = 'mobile';
 else 
  $type = 'desktop';

然后将图像相应地提供给$type

混合

您也可以将两者混合使用,特别是如果您对屏幕大小(或浏览器的其他属性)比实际用户代理更感兴趣。我经常使用以下策略。

    创建一个设置 cookie 的登录页面(带有闪屏或其他内容)。

    var type = (screen.width > 500) ? 'desktop' : 'mobile';
    document.cookie = 'type=' + type + '; expires=Fri, 31 Dez 2020 00:00:00 UTC; path=/';
    

    然后将用户重定向到主页

    然后使用cookie server端显示正确的图片

【讨论】:

【参考方案2】:

这适用于一两件事。对于站点范围的图像加载偏好,还有其他解决方案。

有关示例,请参阅 this codepen。我已经在开发工具中检查了它,以确保不会加载大图像。

因此,您使用.width() 找到窗口宽度并将其存储在名为(无论您想要什么)的变量中我称之为wWidth。然后是一个 if 语句。如果窗口宽度大于 1200 像素(很糟糕,你不能使用 em)--- THEN,加载这个图像 - 否则,加载这个较小的图像。要将其放入 DOM,请将 html 附加到现有 div 并使用 .appendTo()

$(function () 
    var wWidth = $(window).width();
    if (wWidth > 1200) 
        $('<img  src="http://placehold.it/1200/1200"/>').appendTo('.sidebar');
        $('.sidebar a').hide();

     else 
        $('<img  src="http://placehold.it/600/600" />').appendTo('.sidebar');
    
);

这个例子是针对地图的......所以如果他们想加载谷歌地图,我有一个链接,他们可以点击加载更好的地图。 (但是,如果窗口很大,我就不需要那个链接——所以我用.hide()隐藏了它

编辑 04/2014

截至 2014 年 4 月,我一直在使用 attr() 切换 src,所以这样,您只需将图像用于移动设备,然后如果它是大屏幕,您可以插入更大图像的源...但是随后你加载了 2 张图片......所以你可以改为加载一个 1px x 1px 的空白 gif 或其他东西开始......并给它一个接近你想要的比率的宽度和高度......

a new CodePen here:

HTML

<div class='image-w thing' id='target01'>
  <!-- standard image for small screens or a blank gif or something -->
  <img src='http://placehold.it/640x640&text=Default-image' alt='' />
</div>

jQuery

​​>
var imageSizeThing = function() 

  var windowWidth = $(window).width();

  if ( windowWidth < 501 ) 

    // if you start with a blank gif or something
    $('#target01 img').attr('src','http://placehold.it/640x640&text=Default-image');

   if ( windowWidth > 500 ) 

    $('#target01 img').attr('src','http://placehold.it/1000x1000');

   if ( windowWidth > 900 ) 

    $('#target01 img').attr('src','http://placehold.it/1800x1800');

   if ( windowWidth > 1200 ) 

    $('#target01 img').attr('src','http://placehold.it/2400x2400');

  

;

// call it on DOM ready, and if it makes sense, when the window resizes
$(document).ready(imageSizeThing);

$(window).resize(imageSizeThing); 

【讨论】:

是否应该有一个&lt;noscript&gt; 后备? 我会说不。有了所有的 js 和 angular 等...... - javascript 只是 2015 年及以后的规范。 - (对我来说)【参考方案3】:

您可以根据媒体查询设置图像的显示(但无论如何都会加载)

@media screen and ( min-width: 500px ) 
    #image-id 
        display: block;
    

或者,为了不让图像在较小的屏幕上加载,您可以将图像包装在一个 div 中(例如,使用 id img-container)并执行以下操作:

if(screen.width>500)
    document.getElementById('img-container').innerHTML = "<img src='image_source_url' />";

【讨论】:

这称为条件显示而不是加载 谢谢@ManishJain,我不希望图片加载到小屏幕上,js方案的问题是图片用php随机显示。我假设您可以在 javascript 中使用 php?图像的代码是这样的: " src="" title="" /> 这似乎工作&lt;script&gt; if (document.documentElement.clientWidth &gt; 940) document.write('&lt;img class="&lt;?php echo "ligncenter size-full ".$imgInfo[$randno][id];?&gt;" src="&lt;?php echo $imgInfo[$randno][src];?&gt;" title="&lt;?php echo $imgInfo[$randno][title];?&gt;" alt="&lt;?php echo $imgInfo[$randno][alt];?&gt;" /&gt;'); &lt;/script&gt; 这看起来可行吗?显然我会把 940 改成 500 @Geoff 当然,您可以在 javascript 代码中包含 php 代码(是否属于最佳实践是不同的问题),这里唯一要记住的是,php 代码将之后从服务器编译并发送到浏览器。因此,当您的浏览器呈现您的页面时,它只会看到 javascript 和 html。【参考方案4】:

如果可以的话,我建议使用 div 并将 background-image 属性设置为您需要的图像。您可以使用媒体查询来定位屏幕大小。基本上...

HTML
<div id="splash-image"></div>

CSS
#splash-image 
    background-image: url("small-image.png");


@media only screen and (min-width: 500px) 
    #splash-image 
        background-image: url("big-image.png");
    

【讨论】:

嗨,是的,这将是理想的,但它是一个内容管理的图像。我已经将图像与 php 一起包装在一些 js 中,检查浏览器宽度(参见上面的评论)。好像没问题。。 这仍然会加载两个背景图像。【参考方案5】:
image.load([

    // Test if media query matches
    test : image.mq('only screen and (max-width: 600px)'),

    // load css and js purely for mobile
    yep: ['/assets/mobile.css', '/assets/mobile.js']

  ]);

【讨论】:

这是一种 Modernizr 方法吗?

以上是关于有条件地为响应式设计加载图像的主要内容,如果未能解决你的问题,请参考以下文章

响应式设计 - 媒体查询 - 如何不加载某些图像

成都川软培训响应式网页设计的特点

响应式网页设计和调整图像大小

什么是响应式网站及其特点

响应式设计:如何调整图像/背景图像的大小并垂直对齐 div?

响应式网页设计中的宽度与最大宽度