浏览器兼容性一直是一个前端开发人员不可避免的大问题,这篇文章主要列举了html、css以及javascript中一些常见的兼容性问题以及对应的解决方案。
文中所有的demo下载地址:https://github.com/usecodelee/compatibility
Html&CSS部分:
1. audio&video
一般的做法:
<video controls="controls" autoplay="autoplay" width="512" height="288" src="myvideo.mp4"></video>
更好的做法:
<video width="512" height="288">
<source src="myvideo.mp4" type="video/mp4"></source>
<source src="myvideo.ogv" type="video/ogg"></source>
<source src="myvideo.webm" type="video/webm"></source>
<object width="512" height="288" type="application/x-shockwave-flash" data="myvideo.swf">
<param name="movie" value="myvideo.swf" />
<param name="flashvars" value="autostart=true&file=myvideo.swf" />
</object> 当前浏览器不支持 video直接播放,点击这里下载视频: <a href="myvideo.webm">下载视频</a>
</video>
2. display:inline-block;在ie6、ie7下只有设置在默认显示方式为inline的元素上才会生效,请实现兼容ie6、ie7的通用的方式。
解决方案:
display: inline-block;
*display: inline;
*zoom: 1;
通过 *zoom: 1; 去触发hasLayout的行为,然后通过 *display: inline; 去支持IE7及以下版本(高版本会直接使用display: inline-block;)
当hasLayout和inline在一起的时候,就触发了inline-block的行为在IE7及以下版本。
3. ul和ol列表缩进
消除ul、ol等列表的缩进时,样式应写成:list-style:none;margin:0px;padding:0px;其中margin属性对IE有效,padding属性对FireFox有效。在IE中,设置margin:0px可以去除列表的上下左右缩进、空白以及列表编号或圆点,设置padding对样式没有影响;在 Firefox 中,设置margin:0px仅仅可以去除上下的空白,设置padding:0px后仅仅可以去掉左右缩进,还必须设置list- style:none才 能去除列表编号或圆点。也就是说,在IE中仅仅设置margin:0px即可达到最终效果,而在Firefox中必须同时设置margin:0px、 padding:0px以及list-style:none三项才能达到最终效果。
4. border-radius
语法:
border-radius:[ <length> | <percentage> ]{1,4} [ / [ <length> | <percentage> ]{1,4} ]?
<length>:用长度值设置对象的圆角半径长度。不允许负值
<percentage>:用百分比设置对象的圆角半径长度。不允许负值
border-radius:20px;
兼容方法:
低版本的chrome:-webkit-border-radius:10px;
低版本的firefox:-moz-border-radius:10px;
ie7以下版本不支持圆角
IE6/7/8:引入ie-css3兼容文件,不支持除了黑色(#000)以外的其他颜色
5. IE的双边距bug
设置为float的div在ie下设置的margin会加倍。这是一个ie6都存在的bug。
解决方案:在这个div里面加上display:inline;
例如:
Html:
<div id=”div1”></div>
CSS:
.div2 {
background-color: red;
float: left;
width: 150px;
height: 150px;
margin: 5px 0 5px 100px;
display:inline;
}
6. box-shadow
语法:
box-shadow:none|[inset? && [<offset-x><offset-y><blur-radius>?<spread-radius>?<color>?]]#
inset:设置对象的阴影类型为内阴影。该值为空时,则对象的阴影类型为外阴影
<offset-x>: 这是第一个 length值设置水平偏移量,如果是负值则阴影位于元素左边。
<offset-y>: 这是第二个 length值设置垂直偏移量,如果是负值则阴影位于元素上面。
<blur-radius>:这是第三个 length值。值越大,糊糊面积越大,阴影就越大越淡。 不能为负值。默认为0,此时阴影边缘锐利。
<color>:设置对象的阴影的颜色。
实例:
.div2 {
background-color: red;
float: left;
width: 150px;
height: 150px;
margin: 5px 0 5px 100px;
box-shadow: 20px 20px 10px #ccc;
}
IE7、8:
解决方案:
第一种方法:
filter: progid:dXImageTransform.Microsoft.DropShadow(color=#cccccc, offX=20, offY=20, positives=true);
IE7、8:
第二种方法:
filter: progid:DXImageTransform.Microsoft.Shadow(color='#cccccc', Direction='120', Strength='20');
两种方法都存在的缺点:阴影不能边缘模糊
7. transform
兼容方法:
.transform{ -webkit-transform: x,y; -moz-transform: x,y; -ms-transform: x,y; -o-transform: x,y; transform: x,y; }
垂直翻转:
transform:rotateY(180deg)
IE8及以下:用IE滤镜
filter:fliph;//水平翻转
filter:flipv;//垂直翻转
JavaScript部分:
1. JSON.stringify函数在ie6/7中不支持,如何兼容?
if(!window.JSON) {
window.JSON = {
parse: function(sJson) {
return eval("(" + sJSON + ")");
},
stringify: function(obj) {
var result = "";
for(var key in obj) {
if(typeof obj[key] == "string") {
result += "\"" + key + "\":\"" + obj[key] + "\",";
} else if(obj[key] instanceof RegExp) {
result += "\"" + key + "\":{},";
} else if(typeof obj[key] == "undefined" || obj[key] instanceof Function) {} else if(obj[key] instanceof Array) {
result += "\"" + key + "\":[";
var arr = obj[key];
for(var item in arr) {
if(typeof arr[item] == "string") {
result += "\"" + arr[item] + "\",";
} else if(arr[item] instanceof RegExp) {
result += "{},";
} else if(typeof arr[item] == "undefined" || arr[item] instanceof Function) {
result += null + ",";
} else if(arr[item] instanceof Object) {
result += this.stringify(arr[item]) + ",";
} else {
result += arr[item] + ",";
}
}
result = result.slice(0, -1) + "],"
} else if(obj[key] instanceof Object) {} else {
result += "\"" + key + "\":" + obj[key] + ",";
}
}
return "{" + result.slice(0, -1) + "}";
}
};
}
2. element.children能够获取元素的元素子节点,但是低版本的ie不支持,如何在低版本的ie上兼容类似的功能。
function getElementChildren(element){
if(!element.children){
var element_arr = [];
var list = element.ChildNodes;
for(i=0; i<list.length; i++){
if (list[i].nodetype==1) {
element_arr.push(list[i]);
}
}
return element_arr;
} else{
return element.children;
}
}
3. element.dataset能够获取元素的自定义属性,但是低版本的ie不支持,如何在低版本的ie上兼容类似的功能。
function dataset(element) {
var obj = {};
if(element.dataset) {
return element.dataset;
} else { // console.log(element.attributes);
for(var i = 0; i < element.attributes.length; i++) {
var key = element.attributes[i].nodeName;
if(/^data-\w+$/.test(key)) { //判断是否以data-开头的属性名
var value = element.attributes[i].nodeValue; //值
var keyName = key.match(/^data-(\w+)/)[1]; //键名
obj[keyName] = value; //对象添加属性
}
}
}
return obj;
}
4. window.getComputedStyle能够获取元素的实际样式,但是低版本的ie8及以下不支持,如何在低版本的ie上兼容类似的功能。
//获取当前样式
function getStyle(element, att) {
//特性侦测
if(window.getComputedStyle) {
//优先使用W3C规范
return window.getComputedStyle(element)[att];
} else {
//针对IE9以下兼容
return element.currentStyle[att];
}
}
文中所有的demo下载地址:https://github.com/usecodelee/compatibility