最新做项目要搞个浏览器兼容方案,之前做的兼容不是很好,所以要重新改写,为什么会有那么多不兼容原因(渲染-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);
以上就是我做这个项目兼容的思路,如果有好的方法请指点,有不对的地方欢迎指正(感激不尽)。