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

資訊專欄INFORMATION COLUMN

Zepto 源碼分析 2 - Polyfill 設(shè)計(jì)

chuyao / 2624人閱讀

摘要:此模塊包含的設(shè)計(jì)思路即為預(yù)以匹配降級(jí)方案。沒(méi)有默認(rèn)編譯該模塊,以及利用該模塊判斷后提供平臺(tái)相關(guān)邏輯的主要原因在于其設(shè)計(jì)原則的代碼完成核心的功能。此處,也引出了代碼實(shí)現(xiàn)的另一個(gè)基本原則面向功能標(biāo)準(zhǔn),先功能覆蓋再優(yōu)雅降級(jí)。

在進(jìn)入 Zepto Core 模塊代碼之前,本節(jié)簡(jiǎn)略列舉 Zepto 及其他開(kāi)源庫(kù)中一些 Polyfill 的設(shè)計(jì)思路與實(shí)現(xiàn)技巧。

涉及模塊:IE/IOS 3/Detect.

IE 模塊 / CSSOM 相關(guān) Polyfill

Zepto 的 IE 模塊 src/ie.js 中僅僅包含了一個(gè)兼容性降級(jí)邏輯,雖簡(jiǎn)單其實(shí)現(xiàn)也值得學(xué)習(xí):

(function() {
  try {
    getComputedStyle(undefined);
  } catch (e) {
    var nativeGetComputedStyle = getComputedStyle;
    window.getComputedStyle = function(element, pseudoElement) {
      try {
        return nativeGetComputedStyle(element, pseudoElement);
      } catch (e) {
        return null;
      }
    };
  }
})();

低版本兼容模式(以 IE 7 為例)調(diào)用 getComputedStyle 會(huì)出現(xiàn)找不到該方法的問(wèn)題),已經(jīng)在高版本 IE 獲得支持:

The value of the property "getComputedStyle" is null or undefined, not a Function object

顧名思義該方法用于獲得元素的動(dòng)態(tài)計(jì)算屬性,此處在 windows 對(duì)象上顯式掛載包含 Failover 的 getComputedStyle 方法,使得該方法不存在時(shí)的調(diào)用代碼仍可繼續(xù)運(yùn)行,不行成阻塞。更詳細(xì)的多瀏覽器兼容方案可以通過(guò)閱讀 jQuery css API 源碼找到。

此模塊包含的設(shè)計(jì)思路即為Failover 預(yù) catch以匹配降級(jí)方案。

從該問(wèn)題中可以引申出一個(gè)常見(jiàn)問(wèn)題,CSSOM 的瀏覽器支持程度遠(yuǎn)遠(yuǎn)低于 DOM 的支持程度,W3C 對(duì)于 Document Object Model (DOM) Level 2 Style Specification 的聲明早已于 2000 年末時(shí)刻完成,然而 CSSOM 的官方標(biāo)準(zhǔn) CSS Object Model (CSSOM) 由于 CSS 3 多管道演進(jìn)的實(shí)現(xiàn)方式影響,仍未推出廠商公認(rèn)的實(shí)際標(biāo)準(zhǔn),因此對(duì)于 CSSOM 的操作設(shè)計(jì)與跨瀏覽器兼容性測(cè)試,jQuery 仍有極好的參考價(jià)值。同時(shí),開(kāi)源社區(qū)中也存在大量的 Polyfill(膩?zhàn)幽_本)用于對(duì)低版本瀏覽器通過(guò) JavaScript 附加邏輯的方式附加較新潮的特性,可以在 Modernizr/Modernizr 類似的代碼源中找到。閱讀 Polyfill 往往可以獲得對(duì) 原型鏈和 JS 面向?qū)ο?/strong>設(shè)計(jì)思維的更深刻認(rèn)識(shí),以及更深層次的設(shè)計(jì)技巧,以如下的一個(gè) IE 8 opacity 屬性的 Polyfill 函數(shù)為例,完成該函數(shù)的技巧已經(jīng)遠(yuǎn)遠(yuǎn)超越了自身實(shí)現(xiàn)的功能:

// 正則表達(dá)式,匹配滿足 alpha 定義規(guī)則的字符串
var opacityre = /s*alphas*(s*opacitys*=s*(d+)s*)/;

// 原型鏈掛載,直接將 opacity 放入 CSSStyleDeclaration 中
defineProperty(window.CSSStyleDeclaration.prototype, "opacity", {

  // getter 函數(shù),自定義 toString 方法
  get: function() {
    var m = this.filter.match(opacityre);
    return m ? (m[1] / 100).toString() : "";
  },
  
  // setter 函數(shù),將 opacity 值寫(xiě)入 alpha(opacity=$value) 的形式,供瀏覽器使用
  set: function(value) {
    this.zoom = 1;
    var found = false;
    if (value < 1) {
      value = " alpha(opacity=" + Math.round(value * 100) + ")";
    } else {
      value = "";
    }
    this.filter = this.filter.replace(opacityre, function() {
      found = true;
      return value;
    });
    if (!found && value) {
      this.filter += value;
    }
  }
});

此腳本包含的設(shè)計(jì)思路為利用 Getter/Setter 控制不同上下文中屬性的設(shè)置與獲取,同樣的思路即為 Vue.js 數(shù)據(jù)綁定的設(shè)計(jì)源泉。

IOS 3 模塊 / 語(yǔ)言特性 Polyfill

Zepto 默認(rèn)編譯中未包含的 IOS 3 模塊 src/ios3.js 包含了兩個(gè)函數(shù)的兼容實(shí)現(xiàn),實(shí)際上屬于語(yǔ)言特性 Polyfill,這類 Polyfill 主要用于解決語(yǔ)言發(fā)展與實(shí)現(xiàn)不同步等問(wèn)題,并提供一些實(shí)現(xiàn)良好的公共方法用于業(yè)務(wù)開(kāi)發(fā),最常見(jiàn)的兩類例子:

Lodash / Underscore 提供大量實(shí)現(xiàn)良好的工具函數(shù)

TypeScript 提供類型系統(tǒng),實(shí)際這門(mén)語(yǔ)言也可被當(dāng)做 Polyfill 看,因?yàn)?ECMAScript 提案中,已經(jīng)包含了一個(gè)靜態(tài)類型系統(tǒng) 的建議

IOS 3 模塊中的兩個(gè) Polyfill 分別為 String / Array 兩個(gè)包裝類原型上掛載了一個(gè)常見(jiàn)方法:

    // Line 6
    String.prototype.trim = function() {
      // 將字符串首末的空格剪除
      return this.replace(/^s+|s+$/g, "");
    };

該方法原始定義于 ES 5 標(biāo)準(zhǔn)中的 String.prototype.trim(),此處實(shí)現(xiàn)依賴 ES 5 標(biāo)準(zhǔn)中的 White Space 中的描述。該方法實(shí)現(xiàn)相對(duì)簡(jiǎn)單,同時(shí)也提示了一個(gè)設(shè)計(jì)常識(shí):向公認(rèn)的 API 靠齊,實(shí)現(xiàn)方法核心后提供方法擴(kuò)展,遵循該原則的包括:

Preact 與 React

Zepto 與 jQuery

Lodash 與 Underscore 等

trim() 函數(shù)較為簡(jiǎn)單明確,而 reduce() 方法的實(shí)現(xiàn)與 ES 5 中的 Array.prototype.reduce(callbackfn[,initialValue]) 定義的算法完全相同,更能體現(xiàn)這一原則,此段不進(jìn)行注釋,進(jìn)入 ES 5 規(guī)范中該函數(shù)定義即可對(duì)照理解該 Polyfill 的實(shí)現(xiàn)方法。

  // Line 11
  if (Array.prototype.reduce === undefined)
    Array.prototype.reduce = function(fun) {
      // 略
    };
Detect 模塊 / User Agent 識(shí)別

Detect 模塊用于識(shí)別瀏覽器平臺(tái)類型,默認(rèn)也不處于編譯列表中,其代碼 src/detect.js 組織結(jié)構(gòu)如下:

// Line 5
;(function($){

  // 平臺(tái)偵測(cè)邏輯
  function detect(ua, platform){
  }

  // 傳入 Zepto 及平臺(tái)環(huán)境變量
  detect.call($, navigator.userAgent, navigator.platform)
  // make available to unit tests
  $.__detect = detect

// 將全局變量 Zepto 帶入,化為參數(shù) "$"
})(Zepto)

平臺(tái)偵測(cè)邏輯 function detect(ua, platform) 內(nèi)部為一組大的字符串判斷邏輯,形成這樣雜亂無(wú)章的平臺(tái)判斷邏輯,正是因?yàn)橐淮淮臑g覽器大戰(zhàn)。 User-Agent 字符串被定義為包含了當(dāng)前瀏覽器(規(guī)范名稱 User Agent)信息的 HTTP 頭部標(biāo)識(shí),用于使服務(wù)器可以根據(jù)平臺(tái)完成瀏覽器檢測(cè)并下發(fā)不同的原始代碼用于渲染。由于瀏覽器偽裝等各種原因,UA 實(shí)際并不可信,因此對(duì)于它的偵測(cè)相當(dāng)困難,常見(jiàn) UA 可以從 List of User Agents 頁(yè)面內(nèi)查詢到。

Zepto 沒(méi)有默認(rèn)編譯該模塊,以及利用該模塊判斷后提供平臺(tái)相關(guān)邏輯的主要原因在于其設(shè)計(jì)原則:20% 的代碼完成 jQuery 核心 80% 的功能。此處,也引出了代碼實(shí)現(xiàn)的另一個(gè)基本原則:面向功能/API 標(biāo)準(zhǔn),先功能覆蓋再優(yōu)雅降級(jí)。以提供一個(gè)常見(jiàn)的 Browser Compatibility Matrix 為例,根據(jù)實(shí)現(xiàn)規(guī)格測(cè)試前端產(chǎn)出在不同平臺(tái)的可用性,再提供降級(jí)方案或 Polyfill 以滿足更多的用戶需求。

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

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

相關(guān)文章

  • Zepto 源碼分析 1 - 進(jìn)入 Zepto

    摘要:選擇的理由是一個(gè)用于現(xiàn)代瀏覽器的與大體兼容的庫(kù)。環(huán)境搭建分析環(huán)境的搭建僅需要一個(gè)常規(guī)頁(yè)面和原始代碼一個(gè)常規(guī)頁(yè)面打開(kāi)的首頁(yè)即可,在開(kāi)發(fā)人員工具中即可使用原始代碼本篇分析的代碼參照,進(jìn)入該代碼分支中即可。 選擇 Zepto 的理由 Zepto is a minimalist JavaScript library for modern browsers with a largely jQue...

    Aklman 評(píng)論0 收藏0
  • zepto源碼分析-代碼結(jié)構(gòu)

    摘要:本來(lái)想學(xué)習(xí)一下的源碼,但由于的源碼有多行,設(shè)計(jì)相當(dāng)復(fù)雜,所以決定從開(kāi)始,分析一個(gè)成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。同時(shí)發(fā)表在我的博客源碼分析代碼結(jié)構(gòu) 本來(lái)想學(xué)習(xí)一下jQuery的源碼,但由于jQuery的源碼有10000多行,設(shè)計(jì)相當(dāng)復(fù)雜,所以決定從zepto開(kāi)始,分析一個(gè)成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。 網(wǎng)上也有很多zepto的源碼分析,有的給源碼添加注釋,有的談與jQuery的不同,...

    sherlock221 評(píng)論0 收藏0
  • Zepto 源碼分析 3 - qsa 實(shí)現(xiàn)與工具函數(shù)設(shè)計(jì)

    摘要:承接第一篇末尾內(nèi)容,本部分開(kāi)始進(jìn)入主模塊,分析其設(shè)計(jì)思路與實(shí)現(xiàn)技巧下文代碼均進(jìn)行過(guò)重格式化,但代碼版本同第一部分內(nèi)容且入口函數(shù)不變的選擇器先從第一個(gè)與原型鏈構(gòu)造不直接相關(guān)的工具函數(shù)說(shuō)起,觀察的設(shè)計(jì)思路。 承接第一篇末尾內(nèi)容,本部分開(kāi)始進(jìn)入 zepto 主模塊,分析其設(shè)計(jì)思路與實(shí)現(xiàn)技巧(下文代碼均進(jìn)行過(guò)重格式化,但代碼 Commit 版本同第一部分內(nèi)容且入口函數(shù)不變): Zepto 的選...

    ctriptech 評(píng)論0 收藏0
  • zepto.js 源碼剖析

    摘要:正則首先看一下其中的正則表達(dá)的正則表達(dá)式要包含在中間。后面可以跟來(lái)表示是否進(jìn)行全局匹配或者不區(qū)分大小寫(xiě)匹配。從句首開(kāi)始匹配是一個(gè),匹配一個(gè)空白字符,包括。 正則 首先看一下其中的正則表達(dá): fragmentRE = /^s*]*>/, singleTagRE = /^(?:|)$/, tagExpanderRE = /]*)/>/ig, rootNodeRE = /^(?:body|h...

    winterdawn 評(píng)論0 收藏0
  • Zepto源碼之代碼結(jié)構(gòu)

    摘要:源碼結(jié)構(gòu)整體結(jié)構(gòu)如果在編輯器中將的源碼折疊起來(lái),看到的就跟上面的代碼一樣。參考源碼分析代碼結(jié)構(gòu)對(duì)象思想與源碼分析設(shè)計(jì)和源碼分析源碼中關(guān)于的問(wèn)題最后,所有文章都會(huì)同步發(fā)送到微信公眾號(hào)上,歡迎關(guān)注歡迎提意見(jiàn) 雖然最近工作中沒(méi)有怎么用 zepto ,但是據(jù)說(shuō) zepto 的源碼比較簡(jiǎn)單,而且網(wǎng)上的資料也比較多,所以我就挑了 zepto 下手,希望能為以后閱讀其他框架的源碼打下基礎(chǔ)吧。 源碼版...

    warkiz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<