移动端动态设置字体大小的实例详解

零下一度
Lepaskan: 2017-06-29 11:25:34
asal
1278 orang telah melayarinya

rem由来:font size of the root element,那么rem是个单位,单位大小由它第一代老祖宗的font-size的大小决定。现在前端码农们为了能在各个屏幕上看到一个健康的网页在默默的牺牲着自己的健康,因为不仅要知道rem是个单位,更重要的是要知道怎么能在不同分辨率下呈现的页面都很NB。

事故造成原因:
1.px单位在PC上很流行,在手机屏幕上一看,MLGB的,同样的12px却小的跟蚂蚁似的。
2.好不容易在iPhone4上调的正常了,换个菊花牌手机,MBD不堪入目了。
3.知道了rem的用法,但是html的font-size到底是多少才合适啊啊啊,妈蛋~。

好了,那么现在来解决这些问题。
在解决之前,麻烦各位大婶要了解一些你可能不想了解的东东(警告:不了解这些就不能知道真相哟~):
1.物理像素(physical pixel)
我们看到的每个屏幕都是由一颗颗我们肉眼难以看到的小颗粒(物理像素)组成的。

2.逻辑像素
是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素)。

3.设备的像素比(device pixel ratio)简称DPR
它的数值体现了物理像素和逻辑像素之间的关系,用公式可以计算出该设备的DPR的大小:

DPR = 物理像素 / 逻辑像素
Salin selepas log masuk

那么了解了上面这些概念,就可以知道,为什么css在pc上写着font-size=12px;但是换到手机上却变小了?因为DPR啊啊啊,大哥~。
没错,我们在电脑屏幕上的DPR是1,但是手机却不同,可能是它可能是2,也可能是3。获取设备DPR的方法还是有的:
1.在JavaScript中,通过window.devicePixelRatio来获取
2.在css中,可以通过-webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio进行媒体查询,对不同DPR的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

本人也在网上看了不少动态设置rem的文章,下面把几个常用的列举出来:

一,用媒体查询来设置html的font-size:

@media screen and (min-width: 320px) {html {font-size: 14px;}
}
 
@media screen and (min-width: 360px) {html {font-size: 16px;}
}
 
@media screen and (min-width: 400px) {html {font-size: 18px;}
}
 
@media screen and (min-width: 440px) {html {font-size: 20px;}
}
 
@media screen and (min-width: 480px) {html {font-size: 22px;}
}
 
@media screen and (min-width: 640px) {html {font-size: 28px;}
}
Salin selepas log masuk

二、利用js来动态设置

!(function(doc, win) {var docEle = doc.documentElement,
        evt = "onorientationchange" in window ? "orientationchange" : "resize",
        fn = function() {var width = docEle.clientWidth;
            width && (docEle.style.fontSize = 20 * (width / 320) + "px");
        };
     
    win.addEventListener(evt, fn, false);
    doc.addEventListener("DOMContentLoaded", fn, false);
 
}(document, window));
Salin selepas log masuk

我要说的是最后一种,也是我认为目前比较好的实现方法:
利用js计算当前设备的DPR,动态设置在html标签上,并动态设置html的font-size,利用css的选择器根据DPR来设置不同DPR下的字体大小(这个方法很不错哦~)

<span style="font-size: 18px"><code>!<span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">win, lib) {<span class="hljs-keyword">var timer,
        doc     = win.document,
        docElem = doc.documentElement,

        vpMeta   = doc.querySelector(<span class="hljs-string">&#39;meta[name="viewport"]&#39;),
        flexMeta = doc.querySelector(<span class="hljs-string">&#39;meta[name="flexible"]&#39;),
 
        dpr   = <span class="hljs-number">0,
        scale = <span class="hljs-number">0,
 
        flexible = lib.flexible || (lib.flexible = {}); <span class="hljs-comment">// 设置了 viewport meta<span class="hljs-keyword">if (vpMeta) { <span class="hljs-built_in">console.warn(<span class="hljs-string">"将根据已有的meta标签来设置缩放比例");<span class="hljs-keyword">var initial = vpMeta.getAttribute(<span class="hljs-string">"content").match(<span class="hljs-regexp">/initial\-scale=([\d\.]+)/); <span class="hljs-keyword">if (initial) {
            scale = <span class="hljs-built_in">parseFloat(initial[<span class="hljs-number">1]); <span class="hljs-comment">// 已设置的 initialScale
            dpr = <span class="hljs-built_in">parseInt(<span class="hljs-number">1 / scale);      <span class="hljs-comment">// 设备像素比 devicePixelRatio
        }
 
    }<span class="hljs-comment">// 设置了 flexible Meta<span class="hljs-keyword">else <span class="hljs-keyword">if (flexMeta) {<span class="hljs-keyword">var flexMetaContent = flexMeta.getAttribute(<span class="hljs-string">"content");<span class="hljs-keyword">if (flexMetaContent) { <span class="hljs-keyword">var initial = flexMetaContent.match(<span class="hljs-regexp">/initial\-dpr=([\d\.]+)/),
                maximum = flexMetaContent.match(<span class="hljs-regexp">/maximum\-dpr=([\d\.]+)/); <span class="hljs-keyword">if (initial) {
                dpr = <span class="hljs-built_in">parseFloat(initial[<span class="hljs-number">1]);
                scale = <span class="hljs-built_in">parseFloat((<span class="hljs-number">1 / dpr).toFixed(<span class="hljs-number">2));
            } <span class="hljs-keyword">if (maximum) {
                dpr = <span class="hljs-built_in">parseFloat(maximum[<span class="hljs-number">1]);
                scale = <span class="hljs-built_in">parseFloat((<span class="hljs-number">1 / dpr).toFixed(<span class="hljs-number">2));
            }
        }
    } <span class="hljs-comment">// viewport 或 flexible<span class="hljs-comment">// meta 均未设置<span class="hljs-keyword">if (!dpr && !scale) {<span class="hljs-comment">// QST<span class="hljs-comment">// 这里的 第一句有什么用 ?<span class="hljs-comment">// 和 Android 有毛关系 ?<span class="hljs-keyword">var u = (win.navigator.appVersion.match(<span class="hljs-regexp">/android/gi), win.navigator.appVersion.match(<span class="hljs-regexp">/iphone/gi)),
            _dpr = win.devicePixelRatio; <span class="hljs-comment">// 所以这里似乎是将所有 Android 设备都设置为 1 了
        dpr = u ? ( (_dpr >= <span class="hljs-number">3 && (!dpr || dpr >= <span class="hljs-number">3))
                        ? <span class="hljs-number">3
                        : (_dpr >= <span class="hljs-number">2 && (!dpr || dpr >= <span class="hljs-number">2))
                            ? <span class="hljs-number">2
                            : <span class="hljs-number">1
                  )
                : <span class="hljs-number">1;
 
        scale = <span class="hljs-number">1 / dpr;
    }
 
    docElem.setAttribute(<span class="hljs-string">"data-dpr", dpr); <span class="hljs-comment">// 插入 viewport meta<span class="hljs-keyword">if (!vpMeta) {
        vpMeta = doc.createElement(<span class="hljs-string">"meta");
         
        vpMeta.setAttribute(<span class="hljs-string">"name", <span class="hljs-string">"viewport");
        vpMeta.setAttribute(<span class="hljs-string">"content",<span class="hljs-string">"initial-scale=" + scale + <span class="hljs-string">", maximum-scale=" + scale + <span class="hljs-string">", minimum-scale=" + scale + <span class="hljs-string">", user-scalable=no"); <span class="hljs-keyword">if (docElem.firstElementChild) {
            docElem.firstElementChild.appendChild(vpMeta)
        } <span class="hljs-keyword">else {<span class="hljs-keyword">var div = doc.createElement(<span class="hljs-string">"div");
            div.appendChild(vpMeta);
            doc.write(div.innerHTML);
        }
    } <span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">setFontSize(<span class="hljs-params">) {<span class="hljs-keyword">var winWidth = docElem.getBoundingClientRect().width; <span class="hljs-keyword">if (winWidth / dpr > <span class="hljs-number">540) {
            (winWidth = <span class="hljs-number">540 * dpr);
        } <span class="hljs-comment">// 根节点 fontSize 根据宽度决定<span class="hljs-keyword">var baseSize = winWidth / <span class="hljs-number">10;
 
        docElem.style.fontSize = baseSize + <span class="hljs-string">"px";
        flexible.rem = win.rem = baseSize;
    } <span class="hljs-comment">// 调整窗口时重置
    win.addEventListener(<span class="hljs-string">"resize", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">) {
        clearTimeout(timer);
        timer = setTimeout(setFontSize, <span class="hljs-number">300);
    }, <span class="hljs-literal">false); 
     <span class="hljs-comment">// 这一段是我自己加的<span class="hljs-comment">// orientationchange 时也需要重算下吧
    win.addEventListener(<span class="hljs-string">"orientationchange", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">) {
        clearTimeout(timer);
        timer = setTimeout(setFontSize, <span class="hljs-number">300);
    }, <span class="hljs-literal">false); 
 <span class="hljs-comment">// pageshow<span class="hljs-comment">// keyword: 倒退 缓存相关
    win.addEventListener(<span class="hljs-string">"pageshow", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e) {<span class="hljs-keyword">if (e.persisted) {
            clearTimeout(timer);
            timer = setTimeout(setFontSize, <span class="hljs-number">300);
        }
    }, <span class="hljs-literal">false); <span class="hljs-comment">// 设置基准字体<span class="hljs-keyword">if (<span class="hljs-string">"complete" === doc.readyState) {
        doc.body.style.fontSize = <span class="hljs-number">12 * dpr + <span class="hljs-string">"px";
    } <span class="hljs-keyword">else {
        doc.addEventListener(<span class="hljs-string">"DOMContentLoaded", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">) {
            doc.body.style.fontSize = <span class="hljs-number">12 * dpr + <span class="hljs-string">"px";
        }, <span class="hljs-literal">false);
    }
  
    setFontSize();
 
    flexible.dpr = win.dpr = dpr;
 
    flexible.refreshRem = setFontSize;
 
    flexible.rem2px = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">d) {<span class="hljs-keyword">var c = <span class="hljs-built_in">parseFloat(d) * <span class="hljs-keyword">this.rem;<span class="hljs-keyword">if (<span class="hljs-string">"string" == <span class="hljs-keyword">typeof d && d.match(<span class="hljs-regexp">/rem$/)) {
            c += <span class="hljs-string">"px";
        }<span class="hljs-keyword">return c;
    };
 
    flexible.px2rem = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">d) {<span class="hljs-keyword">var c = <span class="hljs-built_in">parseFloat(d) / <span class="hljs-keyword">this.rem;         <span class="hljs-keyword">if (<span class="hljs-string">"string" == <span class="hljs-keyword">typeof d && d.match(<span class="hljs-regexp">/px$/)) {
            c += <span class="hljs-string">"rem";
        }<span class="hljs-keyword">return c;
    }
}(<span class="hljs-built_in">window, <span class="hljs-built_in">window.lib || (<span class="hljs-built_in">window.lib = {}));<br/><br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>手机淘宝很多页面用的就是这种方法来适配终端的。<br/><br/><br/><br/></span>
Salin selepas log masuk

Atas ialah kandungan terperinci 移动端动态设置字体大小的实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!