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