最新做項目要搞個瀏覽器兼容方案,之前做的兼容不是很好,所以要重新改寫,爲什麼會有那麼多不兼容原因(渲染-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 功能支持情況,這裏我推薦幾個工具Modernizr,ES-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);
以上就是我做這個項目兼容的思路,如果有好的方法請指點,有不對的地方歡迎指正(感激不盡)。