瀏覽器嗅探和兼容淺談

最新做項目要搞個瀏覽器兼容方案,之前做的兼容不是很好,所以要重新改寫,爲什麼會有那麼多不兼容原因(渲染-HTML相關,渲染-CSS相關,渲染-混合類型,腳本,服務端通信,瀏覽器特性),所以做兼容主要從下面幾個方向去分析問題(包括測試)。

1.html標籤

我們做項目些html的時候,應該是要知道標籤的兼容性(主要看HTML5支持情況),比如兼容什麼瀏覽器,儘量不要些一樣兼容性不好的標籤,讓標籤兼容各大主流瀏覽器,可以通過(https://caniuse.com/)查詢。

2.Css樣式

和標籤一樣,寫css時候儘量寫兼容比較好的樣式(主要看Css3支持情況),有些Css3的屬性儘量加上前綴讓它兼容各大主流瀏覽器,併兼容到低版本,可以通過(https://caniuse.com/)查詢。

3.js

寫js時候碰到自己不確定的方法最好去查下方法的兼容性,如果兼容性不是很好果斷換其他的方法實現,不要因爲省代碼而偷懶,到後面你要把之前偷懶的工作量全補回來,可以通過(http://kangax.github.io/compat-table/es6/)查詢js支持情況。

4.瀏覽器嗅探

主要這個是判斷瀏覽器類型,這裏我比較推薦Browser.js,因爲它可以測試出所有瀏覽器的內核(不懂內核可以點擊這裏),官網(http://gucong3000.github.io/browser.js/

5.瀏覽器兼容

拿我這個項目來說(不允許用es6的),已經用了怎麼辦,那麼試試es6-shim https://github.com/paulmillr/es6-shim,polyfill(指的是符合shim標準的API。polyfill API使用老方法來實現新功能,從而保證在低級瀏覽器中也能使用比較新的方法。)

6.代碼生成

比如說less生成css代碼時候是否能直接加上前綴等,或者這麼說生成之後的代碼是否兼容。

7.特性

檢測瀏覽器對 CSS3,HTML5,js 功能支持情況,這裏我推薦幾個工具ModernizrES-Checker

我這個項目是做完之後再做兼容,所以比較麻煩,首先我把所有的html,css,js查詢了兼容並列出各大主流瀏覽器最低版本。
因爲有很多js用了es6語法,甚至es7的,下面版本是用了polyfill.js之後的最低版本。

browserMiniVersion: {
	Opera: 34,
	MSIE: 11,
	Edge: 17,
	Safari: 9,
	Firefox: 43,
	Chrome:33,
}

因爲項目中用到很多js都不兼容(並不只包括es6,es7),如果你覺得這個方法兼容性不好,我想把它兼容到更低,你就可以把它重寫放到這個polyfill.js裏面,由於重寫的方法很多,只寫一個,看下面代碼:

        var compatibleMethods = {
            //Array.prototype.find方法的改寫
            "Array.prototype.find": function (predicate) {
                try {
                    //檢測this是否是null和underfinded(報錯),不是的話返回this。
                    var list = ES.ToObject(this);
                    //檢測list.length是否是symbol類型(報錯),並強制轉換成number類型,並判斷是否是NaN,Finite。
                    var length = ES.ToLength(list.length);
                    //檢測參數是否是 "function"類型
                    if (!E.IsCallable(predicate)) {
                        throw new TypeError('Array#find: predicate must be a function');
                    };
                    var thisArg = arguments.length > 1 ? arguments[1] : null;
                    for (var i = 0, value; i < length; i++) {
                        value = list[i];
                        if (thisArg) {
                            // 相當predicate.call(thisArg, value, i, list)
                            if (Function.call.bind(Function.call)(predicate, thisArg, value, i, list)) {
                                return value;
                            };
                        } else if (predicate(value, i, list)) {
                            return value;
                        };
                    };
                } catch (e) {
                    alert('瀏覽器版本太低,請升級您的瀏覽器');
                    throw new Error(e);
                };

            }
        };
               //遍歷方法對象
       for (var key in compatibleMethods) {
            //判斷瀏覽器支持不支持對象裏面的方法,不支持就使用改寫的方法
            if (!typeof eval(compatibleMethods[key]) === 'function') {
                eval(key + "=" + compatibleMethods[key]);
            };
        };

    };
    exports.polyfill=polyfill;

思路是把要重寫的方法放到一個對象裏面(可以寫很多),下面會遍歷這個對象,不支持的話就運行重寫的方法,如果重寫還不兼容直接給出升級瀏覽器提示。polyfill寫好了,然後可以根據瀏覽器嗅探和我列出的最低瀏覽器兼容版本比較,如果在列表版本之上,執行polyfill,否者直接給出提示。

		var	browserMiniVersion: {
				Opera: 34,
				MSIE: 11,
				Edge: 17,
				Safari: 9,
				Firefox: 43,
				Chrome:33,
			},
			/**
			 * @description 獲取當前瀏覽器版本信息
			 */
		
			getBrowserInformation: {
				browser: browser.OPR ? "Opera" : (browser.Gecko ? "Firefox" : Object.keys(browser)[0]),
				version: browser.OPR || browser[Object.keys(browser)[0]]
			},
			/**
			 * @param {Object} browserVersion  瀏覽器版本信息
			 * @description 根據瀏覽器信息,如果能嗅探出,和當前給出的版本對比,不能嗅探,直接讀取兼容方法(還不兼容給出錯誤提示)
			 */
			browserController: function (browserVersion) {
				if (browserVersion.version && this.browserMiniVersion[browserVersion.browser]) {
					//ie內核取出來的版本是number類型
					var index =	typeof browserVersion.version === "string" ? browserVersion.version.indexOf('.') : -1;
					//取出版本號
					browserVersion.version = index>0 ? browserVersion.version.slice(0,index) : browserVersion.version;
					//比較版本
					browserVersion.version >= this.browserMiniVersion[browserVersion.browser] ? polyfill.compatibility() : alert(
						'瀏覽器版本不支持,請升級瀏覽器版本')
				};
			},
		}
		browserCompatibility.browserController(browserCompatibility.getBrowserInformation);

以上就是我做這個項目兼容的思路,如果有好的方法請指點,有不對的地方歡迎指正(感激不盡)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章