zoukankan      html  css  js  c++  java
  • 移动开发中更好的图片自适应

    一直以来,我们在 PC 端开发中,都要求给图片写上一个宽高,以避免图片加载后造成的 reflow 。但在移动端开发中,为了能适配各种各样的屏幕尺寸,我们都不会像在PC端中一样给图片设定固定的宽高,美其名曰:响应式图片

    一般做法是:

    img{ 100%;}
    

    更好的写法是:

    img{max- 100%;}
    

    更好的写法好处是避免当图片尺寸小于屏幕尺寸时,拉伸造成图片失真,影响体验。

    按上面的方式处理,图片就能根据屏幕大小自动等比缩放,达到响应式的效果。大多数情况下已经满足我们日常的开发需求,但在一些特殊需求里,如图片后面有内容,图片做按需加载,或者图片做一个进场动画,这时,当图片加载前和加载后,会造成 reflow,在视觉体验上我们就看到内容在图片出来前后有一个跳动,一定程度上影响了我们的体验。作为一名新时代的切图仔,我们应该解决这个问题。

    我们要的其实很简单,就是在不同屏幕大小,图片能等比缩放显示,单位 px 肯定是不行的了,我们需要一个相对的单位,上面的 % 是一个,但会有 reflow 问题。目前较好的选择是 rem, 它是相对于根元素的相对单位,也就是说,如果我们根据屏幕等比动态地更新根节点的 font-size 值,通过 rem 就能自动更新图片的大小。所以,如下方案:

    更好的自适应: js + rem

    • JS 动态给 html 设置一个跟屏幕宽度成正比的 font-size
    • 图片宽高用 rem 做单位

    ** 与屏幕宽度成正比的 font-size **

    var docEl = document.documentElement;
    docEl.style.fontSize = docEl.getBoundingClientRect().width / 16;
    

    如上 JS ,我们用浏览器的默认字体大小作为基数(这里没有绝对关系,可以用任意数值)。
    假设我们的设计稿是按 640 宽来设计的,图片为 600x300。 那么,得到的 font-size 是 40,也就是说,在样式里,我们需要将图片的宽高除以 40 转换成相应的 rem 单位,得到的值为 15rem; height: 7.5rem,在 iphone4 下效果如图:

    Alt text

    图片显示的宽高为等比,测试链接: http://jsbin.com/qirifadiyu/1/

    这样子,图片既能够自适应,又有大小,就不会有 reflow 造成的跳动现象。一切看起来很美好,但其实有一定限制。

    ** 限制: ** 按 640 宽来设计的页面,理论上我们切出来的图片不会大于 640,但如果一定要用大于 640 的图片,这样子换算后图片的宽度就会大于屏幕宽度,就达不到我们要的效果了。这时可以以屏幕宽度为基值,如 height = 图片高度 * 16 / 图片宽度。

    完整的 JS 如下:

    ;(function(win){
        var docEl = document.documentElement,
            timer = null,
            rem;
    
        function setUnit(){
            rem = docEl.getBoundingClientRect().width / 16;
            docEl.style.fontSize = rem + 'px';
        }
    
        win.addEventListener('resize', function() {
            clearTimeout(timer);
            timer = setTimeout(setUnit, 300);
        }, false);
        win.addEventListener('pageshow', function(e) {
            if (e.persisted) {
                clearTimeout(timer);
                timer = setTimeout(setUnit, 300);
            }
        }, false);
    
        setUnit();
    })(window);
    

    纯CSS更好的解决方案

    ** html **

    <div class="pic-wrap">
        <img src="http://ww3.sinaimg.cn/mw690/69243898gw1emmeiydzvrj20go08cglu.jpg" alt=""/>
    </div>
    

    ** css **

    .pic-wrap{position: relative; padding-top: 50%;}
    .pic-wrap img{position: absolute; left: 0; top: 0;  100%; max- 640px;}
    

    此方法依赖于一定的结构,但相对于上一个方法来说,不需要依赖 JS。因为 padding 的百分比值是相对于宽度的,也就是有了跟屏幕宽度成正比的条件,所以利用 padding-top 设置与宽高等比的百分比值占位,就实现了同样的效果。

    计算公式: padding-top: 图片高度 * 100% / 图片宽度。

    测试链接: http://jsbin.com/cexazepuvi/1/

    参考文档

    手机淘宝的flexible设计与实现

  • 相关阅读:
    Codevs_1403_新三国争霸_(Kruskal+动态规划)
    BZOJ_1084_[SCOI2005]_最大子矩阵_(动态规划)
    BZOJ_1180_[CROATIAN2009]_OTOCI_(LCT)
    BZOJ_1611_[Usaco2008_Feb]_Meteor_Shower流星雨_(bfs)
    hdu5338 (二进制,双指针)
    并查集专辑 (poj1182食物链,hdu3038, poj1733, poj1984, zoj3261)
    生成树专题
    生成树相关问题
    uvaLive5713 次小生成树
    如何将无向图变为点/边双连通,如何将有向图变为强连通图
  • 原文地址:https://www.cnblogs.com/littledu/p/4169077.html
Copyright © 2011-2022 走看看