亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

libflexible源碼閱讀

icattlecoder / 2883人閱讀

摘要:前言最近需要一款移動端的產(chǎn)品,當(dāng)時需要趕工期,在參考了天貓的布局和手淘的布局方案后,決定選用。首先我們需要通過獲得的寬度,然后將寬度分為份,份為。當(dāng)然這還是有一點(diǎn)點(diǎn)問題的因?yàn)檫@樣將不會是的滿屏了。

前言

最近需要一款移動端的產(chǎn)品,當(dāng)時需要趕工期,在參考了天貓的flexbox布局和手淘的
rem布局方案后,決定選用libflexible。做完項(xiàng)目之后,稍有空閑時間,決定看看libflexible
如何實(shí)現(xiàn)動態(tài)設(shè)置根元素的字體,從而通過rem的方式改變其他元素大小

正文

首先我們看一下flexible需要哪些屬性

;(function(win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector("meta[name="viewport"]");
    var flexibleEl = doc.querySelector("meta[name="flexible"]");
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = {});

在函數(shù)運(yùn)行時,我們需要將windows對象注入,然后在看看windows下是否已經(jīng)存在lib(即是否已經(jīng)有
使用過flexible)了,注入完之后,我們依次獲得doc,docEl,metaEl,flexibleEl,其中metaEl
是為了判斷我們是否已經(jīng)有預(yù)設(shè)好的viewport,flexibleEl則是判斷我們已經(jīng)手動設(shè)置好dpr來避免
flexible庫動態(tài)設(shè)置dpr

if (metaEl) {
     console.warn("將根據(jù)已有的meta標(biāo)簽來設(shè)置縮放比例");
     var match = metaEl.getAttribute("content").match(/initial-scale=([d.]+)/);
     if (match) {
         scale = parseFloat(match[1]);
         dpr = parseInt(1 / scale);
     }
 }

如果metaEl存在的話,意味著頁面上存在形如的標(biāo)簽,此時我們已經(jīng)明確了我們需要的縮放,不再需要flexible的介入,縮放值scale直接
使用預(yù)設(shè)的initial-scale,通過我們預(yù)設(shè)的的縮放,我們的layout viewport將會是 ideal viewport/scale,如果我們的initual-scale為1的話
且ideal為414px的話,我們的layout viewport將會是414px

else if (flexibleEl) {
       var content = flexibleEl.getAttribute("content");
       if (content) {
           var initialDpr = content.match(/initial-dpr=([d.]+)/);
           var maximumDpr = content.match(/maximum-dpr=([d.]+)/);
           if (initialDpr) {
               dpr = parseFloat(initialDpr[1]);
               scale = parseFloat((1 / dpr).toFixed(2));
           }
           if (maximumDpr) {
               dpr = parseFloat(maximumDpr[1]);
               scale = parseFloat((1 / dpr).toFixed(2));
           }
       }
   }

如果我們沒有設(shè)置初始的viewport但是有這樣的flexible自身的預(yù)設(shè)
那么我們將會有預(yù)設(shè)的dpr,此時flexible將根據(jù)我們預(yù)設(shè)的dpr通過scale=1/dpr的方式來計(jì)算出我們的縮放,進(jìn)而影響layout viewport
的大小

if (!dpr && !scale) {
       var isAndroid = win.navigator.appVersion.match(/android/gi);
       var isIPhone = win.navigator.appVersion.match(/iphone/gi);
       var devicePixelRatio = win.devicePixelRatio;
       if (isIPhone) {
           // iOS下,對于2和3的屏,用2倍的方案,其余的用1倍方案
           if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
               dpr = 3;
           } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
               dpr = 2;
           } else {
               dpr = 1;
           }
       } else {
           // 其他設(shè)備下,仍舊使用1倍的方案
           dpr = 1;
       }
       scale = 1 / dpr;
   }

接下來,如果我們既沒有通過這種方式預(yù)設(shè)dpr,
也沒有通過的方式預(yù)設(shè)縮放,此時flexible開始根據(jù)
設(shè)備的dpr來動態(tài)計(jì)算縮放。對于非蘋果設(shè)備,flexible設(shè)置dpr為1,對于蘋果設(shè)備,iPhone3以下非retina屏,dpr為1
iPhone4-iPhone6為retina屏,dpr為2,iPhone6Plus為retina HD屏,dpr為3,由于flexible是一個專注于移動端
的解決方案,所以平板(包括iPad)或者桌面端的dpr都為1

docEl.setAttribute("data-dpr", dpr);
 if (!metaEl) {
     metaEl = doc.createElement("meta");
     metaEl.setAttribute("name", "viewport");
     metaEl.setAttribute("content", "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no");
     if (docEl.firstElementChild) {
         docEl.firstElementChild.appendChild(metaEl);
     } else {
         var wrap = doc.createElement("div");
         wrap.appendChild(metaEl);
         doc.write(wrap.innerHTML);
     }
 }

計(jì)算完縮放后,將獲取的dpr值設(shè)置到根元素上,這樣我們就可以通過以下方式:

.selector {
    width: 2rem;
    border: 1px solid #ffffd;
}
[data-dpr="1"] .selector {
    height: 32px;
    font-size: 14px;
}
[data-dpr="2"] .selector {
    height: 64px;
    font-size: 28px;
}
[data-dpr="3"] .selector {
    height: 96px;
    font-size: 42px;
}

為不同dpr的屏幕設(shè)置不同的字體大小,字體之所以不用rem布局,是因?yàn)?/p>

我們不希望文本在Retina屏幕下變小,另外,我們希望在大屏手機(jī)上看到更多文本,以及,現(xiàn)在絕大多數(shù)的字體文件都自帶一些點(diǎn)陣尺寸,通常是16px和24px,所以我們不希望出現(xiàn)13px和15px這樣的奇葩尺寸。

同時當(dāng)不存在metaEl時,flexible動態(tài)生成一條
的標(biāo)簽,如果下存在元素(如等元素)那么,將meta標(biāo)簽插入,如果沒有,就將meta標(biāo)簽用一個div包裝,然后
通過document.write寫入到文檔中

function refreshRem(){
       var width = docEl.getBoundingClientRect().width;
       if (width / dpr > 540) {
           width = 540 * dpr;
       }
       var rem = width / 10;
       docEl.style.fontSize = rem + "px";
       flexible.rem = win.rem = rem;
   }

好了,縮放和dpr都設(shè)置好了,下一步我們要設(shè)置根元素的font-size了,這樣我們可以通過rem的方式
適配不同屏幕。首先我們需要通過docEl.getBoundingClientRect().width獲得layout viewport的寬度,
然后將layout viewport寬度分為10份,1份為1rem。至于設(shè)置540px,是為了讓在ipad橫屏這種情況下瀏覽頁面,不至于因?yàn)槔爝m配后體驗(yàn)太差。當(dāng)然這還是有一點(diǎn)點(diǎn)問題的
因?yàn)檫@樣10rem將不會是ipad的滿屏了。當(dāng)然這是移動端解決方案,并沒有考慮平板和桌面端

win.addEventListener("resize", function() {
      clearTimeout(tid);
      tid = setTimeout(refreshRem, 300);
  }, false);
  win.addEventListener("pageshow", function(e) {
      if (e.persisted) {
          clearTimeout(tid);
          tid = setTimeout(refreshRem, 300);
      }
  }, false);

接著當(dāng)窗口發(fā)生變化或者頁面重新從緩存中載入時,我們都要重新設(shè)置尺寸

if (doc.readyState === "complete") {
       doc.body.style.fontSize = 12 * dpr + "px";
   } else {
       doc.addEventListener("DOMContentLoaded", function(e) {
           doc.body.style.fontSize = 12 * dpr + "px";
       }, false);
   }

body上設(shè)置12 * dpr的font-size值,為了重置頁面中的字體默認(rèn)值,不然沒有設(shè)置font-size的元素會繼承html上的font-size,變得很大。

flexible.dpr = win.dpr = dpr;
        flexible.refreshRem = refreshRem;
        flexible.rem2px = function ( d ) {
            var val = parseFloat ( d ) * this.rem;
            if ( typeof d === "string" && d.match ( /rem$/ ) ) {
                val += "px";
            }
            return val;
        }
        flexible.px2rem = function ( d ) {
            var val = parseFloat ( d ) / this.rem;
            if ( typeof d === "string" && d.match ( /px$/ ) ) {
                val += "rem";
            }
            return val;
        }

最后,flexible提供了兩個工具函數(shù)px2rem和rem2px,這里就不在闡述了

總結(jié)

看完flexible,實(shí)實(shí)在在的感受到rem布局的妙處,通過動態(tài)設(shè)置縮放系數(shù)的方式,
讓layout viewport與設(shè)計(jì)圖對應(yīng),極大地方便了重構(gòu),同時也避免了1px的問題,
然而略有遺憾的就是在安卓和ipad上的表現(xiàn)不佳了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/88232.html

相關(guān)文章

  • 一篇文章把本該屬于你的源碼天賦還給你

    摘要:一些方法不應(yīng)該這樣不應(yīng)該漫無目的地隨手拿起一分源碼,試圖去通讀。應(yīng)該這樣精心挑選要閱讀的源碼項(xiàng)目。這最好是與你的編程語言你的工作內(nèi)容你的興趣所在相關(guān)的,這樣才能更切實(shí)地感受到閱讀源碼給你帶來的益處,更有動力繼續(xù)。 showImg(https://segmentfault.com/img/bVbcvmm?w=785&h=525); 怎么閱讀源碼 沒有經(jīng)驗(yàn)的技術(shù)差底子薄的初級程序員,如何閱...

    chanjarster 評論0 收藏0
  • 精讀《源碼學(xué)習(xí)》

    摘要:精讀原文介紹了學(xué)習(xí)源碼的兩個技巧,并利用實(shí)例說明了源碼學(xué)習(xí)過程中可以學(xué)到許多周邊知識,都讓我們受益匪淺。討論地址是精讀源碼學(xué)習(xí)如果你想?yún)⑴c討論,請點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。 1. 引言 javascript-knowledge-reading-source-code 這篇文章介紹了閱讀源碼的重要性,精讀系列也已有八期源碼系列文章,分別是: 精讀《Immer.js》源...

    aboutU 評論0 收藏0
  • android高級工程師-閱讀源碼的經(jīng)驗(yàn)總結(jié)

    摘要:對于一個有追求的程序員來說必須讀源碼,當(dāng)然閱讀源碼是一件令人頭疼的事。和差不多,想法一樣,但是和相比,搜索到的有價(jià)值結(jié)果不是很多,沒有的理想,還有一些來著百度知道。 對于一個有追求的程序員來說必須讀源碼,當(dāng)然閱讀源碼是一件令人頭疼的事。閱讀別人的代碼遠(yuǎn)比自己寫代碼要難。Linus 是Linux的早期作者,一句影響深遠(yuǎn)的話是Read The Fucking Source Code(RTF...

    idisfkj 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<