摘要:此模塊包含的設(shè)計思路即為預(yù)以匹配降級方案。沒有默認(rèn)編譯該模塊,以及利用該模塊判斷后提供平臺相關(guān)邏輯的主要原因在于其設(shè)計原則的代碼完成核心的功能。此處,也引出了代碼實現(xiàn)的另一個基本原則面向功能標(biāo)準(zhǔn),先功能覆蓋再優(yōu)雅降級。
在進入 Zepto Core 模塊代碼之前,本節(jié)簡略列舉 Zepto 及其他開源庫中一些 Polyfill 的設(shè)計思路與實現(xiàn)技巧。
涉及模塊:IE/IOS 3/Detect.
IE 模塊 / CSSOM 相關(guān) PolyfillZepto 的 IE 模塊 src/ie.js 中僅僅包含了一個兼容性降級邏輯,雖簡單其實現(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 會出現(xiàn)找不到該方法的問題),已經(jīng)在高版本 IE 獲得支持:
The value of the property "getComputedStyle" is null or undefined, not a Function object
顧名思義該方法用于獲得元素的動態(tài)計算屬性,此處在 windows 對象上顯式掛載包含 Failover 的 getComputedStyle 方法,使得該方法不存在時的調(diào)用代碼仍可繼續(xù)運行,不行成阻塞。更詳細(xì)的多瀏覽器兼容方案可以通過閱讀 jQuery css API 源碼找到。
此模塊包含的設(shè)計思路即為Failover 預(yù) catch以匹配降級方案。
從該問題中可以引申出一個常見問題,CSSOM 的瀏覽器支持程度遠(yuǎn)遠(yuǎn)低于 DOM 的支持程度,W3C 對于 Document Object Model (DOM) Level 2 Style Specification 的聲明早已于 2000 年末時刻完成,然而 CSSOM 的官方標(biāo)準(zhǔn) CSS Object Model (CSSOM) 由于 CSS 3 多管道演進的實現(xiàn)方式影響,仍未推出廠商公認(rèn)的實際標(biāo)準(zhǔn),因此對于 CSSOM 的操作設(shè)計與跨瀏覽器兼容性測試,jQuery 仍有極好的參考價值。同時,開源社區(qū)中也存在大量的 Polyfill(膩子腳本)用于對低版本瀏覽器通過 JavaScript 附加邏輯的方式附加較新潮的特性,可以在 Modernizr/Modernizr 類似的代碼源中找到。閱讀 Polyfill 往往可以獲得對 原型鏈和 JS 面向?qū)ο?/strong>設(shè)計思維的更深刻認(rèn)識,以及更深層次的設(shè)計技巧,以如下的一個 IE 8 opacity 屬性的 Polyfill 函數(shù)為例,完成該函數(shù)的技巧已經(jīng)遠(yuǎn)遠(yuǎn)超越了自身實現(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 值寫入 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è)計思路為利用 Getter/Setter 控制不同上下文中屬性的設(shè)置與獲取,同樣的思路即為 Vue.js 數(shù)據(jù)綁定的設(shè)計源泉。
IOS 3 模塊 / 語言特性 PolyfillZepto 默認(rèn)編譯中未包含的 IOS 3 模塊 src/ios3.js 包含了兩個函數(shù)的兼容實現(xiàn),實際上屬于語言特性 Polyfill,這類 Polyfill 主要用于解決語言發(fā)展與實現(xiàn)不同步等問題,并提供一些實現(xiàn)良好的公共方法用于業(yè)務(wù)開發(fā),最常見的兩類例子:
Lodash / Underscore 提供大量實現(xiàn)良好的工具函數(shù)
TypeScript 提供類型系統(tǒng),實際這門語言也可被當(dāng)做 Polyfill 看,因為 ECMAScript 提案中,已經(jīng)包含了一個靜態(tài)類型系統(tǒng) 的建議
IOS 3 模塊中的兩個 Polyfill 分別為 String / Array 兩個包裝類原型上掛載了一個常見方法:
// Line 6 String.prototype.trim = function() { // 將字符串首末的空格剪除 return this.replace(/^s+|s+$/g, ""); };
該方法原始定義于 ES 5 標(biāo)準(zhǔn)中的 String.prototype.trim(),此處實現(xiàn)依賴 ES 5 標(biāo)準(zhǔn)中的 White Space 中的描述。該方法實現(xiàn)相對簡單,同時也提示了一個設(shè)計常識:向公認(rèn)的 API 靠齊,實現(xiàn)方法核心后提供方法擴展,遵循該原則的包括:
Preact 與 React
Zepto 與 jQuery
Lodash 與 Underscore 等
trim() 函數(shù)較為簡單明確,而 reduce() 方法的實現(xiàn)與 ES 5 中的 Array.prototype.reduce(callbackfn[,initialValue]) 定義的算法完全相同,更能體現(xiàn)這一原則,此段不進行注釋,進入 ES 5 規(guī)范中該函數(shù)定義即可對照理解該 Polyfill 的實現(xiàn)方法。
// Line 11 if (Array.prototype.reduce === undefined) Array.prototype.reduce = function(fun) { // 略 };Detect 模塊 / User Agent 識別
Detect 模塊用于識別瀏覽器平臺類型,默認(rèn)也不處于編譯列表中,其代碼 src/detect.js 組織結(jié)構(gòu)如下:
// Line 5 ;(function($){ // 平臺偵測邏輯 function detect(ua, platform){ } // 傳入 Zepto 及平臺環(huán)境變量 detect.call($, navigator.userAgent, navigator.platform) // make available to unit tests $.__detect = detect // 將全局變量 Zepto 帶入,化為參數(shù) "$" })(Zepto)
平臺偵測邏輯 function detect(ua, platform) 內(nèi)部為一組大的字符串判斷邏輯,形成這樣雜亂無章的平臺判斷邏輯,正是因為一代一代的瀏覽器大戰(zhàn)。 User-Agent 字符串被定義為包含了當(dāng)前瀏覽器(規(guī)范名稱 User Agent)信息的 HTTP 頭部標(biāo)識,用于使服務(wù)器可以根據(jù)平臺完成瀏覽器檢測并下發(fā)不同的原始代碼用于渲染。由于瀏覽器偽裝等各種原因,UA 實際并不可信,因此對于它的偵測相當(dāng)困難,常見 UA 可以從 List of User Agents 頁面內(nèi)查詢到。
Zepto 沒有默認(rèn)編譯該模塊,以及利用該模塊判斷后提供平臺相關(guān)邏輯的主要原因在于其設(shè)計原則:20% 的代碼完成 jQuery 核心 80% 的功能。此處,也引出了代碼實現(xiàn)的另一個基本原則:面向功能/API 標(biāo)準(zhǔn),先功能覆蓋再優(yōu)雅降級。以提供一個常見的 Browser Compatibility Matrix 為例,根據(jù)實現(xiàn)規(guī)格測試前端產(chǎn)出在不同平臺的可用性,再提供降級方案或 Polyfill 以滿足更多的用戶需求。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108707.html
摘要:選擇的理由是一個用于現(xiàn)代瀏覽器的與大體兼容的庫。環(huán)境搭建分析環(huán)境的搭建僅需要一個常規(guī)頁面和原始代碼一個常規(guī)頁面打開的首頁即可,在開發(fā)人員工具中即可使用原始代碼本篇分析的代碼參照,進入該代碼分支中即可。 選擇 Zepto 的理由 Zepto is a minimalist JavaScript library for modern browsers with a largely jQue...
摘要:本來想學(xué)習(xí)一下的源碼,但由于的源碼有多行,設(shè)計相當(dāng)復(fù)雜,所以決定從開始,分析一個成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。同時發(fā)表在我的博客源碼分析代碼結(jié)構(gòu) 本來想學(xué)習(xí)一下jQuery的源碼,但由于jQuery的源碼有10000多行,設(shè)計相當(dāng)復(fù)雜,所以決定從zepto開始,分析一個成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。 網(wǎng)上也有很多zepto的源碼分析,有的給源碼添加注釋,有的談與jQuery的不同,...
摘要:承接第一篇末尾內(nèi)容,本部分開始進入主模塊,分析其設(shè)計思路與實現(xiàn)技巧下文代碼均進行過重格式化,但代碼版本同第一部分內(nèi)容且入口函數(shù)不變的選擇器先從第一個與原型鏈構(gòu)造不直接相關(guān)的工具函數(shù)說起,觀察的設(shè)計思路。 承接第一篇末尾內(nèi)容,本部分開始進入 zepto 主模塊,分析其設(shè)計思路與實現(xiàn)技巧(下文代碼均進行過重格式化,但代碼 Commit 版本同第一部分內(nèi)容且入口函數(shù)不變): Zepto 的選...
摘要:正則首先看一下其中的正則表達(dá)的正則表達(dá)式要包含在中間。后面可以跟來表示是否進行全局匹配或者不區(qū)分大小寫匹配。從句首開始匹配是一個,匹配一個空白字符,包括。 正則 首先看一下其中的正則表達(dá): fragmentRE = /^s*]*>/, singleTagRE = /^(?:|)$/, tagExpanderRE = /]*)/>/ig, rootNodeRE = /^(?:body|h...
摘要:源碼結(jié)構(gòu)整體結(jié)構(gòu)如果在編輯器中將的源碼折疊起來,看到的就跟上面的代碼一樣。參考源碼分析代碼結(jié)構(gòu)對象思想與源碼分析設(shè)計和源碼分析源碼中關(guān)于的問題最后,所有文章都會同步發(fā)送到微信公眾號上,歡迎關(guān)注歡迎提意見 雖然最近工作中沒有怎么用 zepto ,但是據(jù)說 zepto 的源碼比較簡單,而且網(wǎng)上的資料也比較多,所以我就挑了 zepto 下手,希望能為以后閱讀其他框架的源碼打下基礎(chǔ)吧。 源碼版...
閱讀 632·2021-08-17 10:15
閱讀 1715·2021-07-30 14:57
閱讀 1970·2019-08-30 15:55
閱讀 2813·2019-08-30 15:55
閱讀 2703·2019-08-30 15:44
閱讀 662·2019-08-30 14:13
閱讀 2380·2019-08-30 13:55
閱讀 2588·2019-08-26 13:56