在javascript中常见的浏览器兼容问题,以及解决方式。
在前端工作当中我们遵循这样的原则:渐进增强和优雅降级
渐进增强(progressive enhancement): 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验
优雅降级(graceful degradation): 一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
1、获取非行内样式:
函数getStyle(e,attr)第一个参数为需要获取样式的元素对象,第二个参数为样式的属性名(可以是一个对象数组)
style 只能获取行内style,
调用方式obj.style.属性
兼容:所有都支持
currentStyle() 可以获取该obj所有style,但是只可以读取,不可以设置
调用方式:obj.currentStyle["属性"] 或者obj.currentStyle.属性
兼容:只兼容ie6以上,不兼容其他浏览器
![](https://i-blog.csdnimg.cn/blog_migrate/ddd85d02376da350eb2481b155c861a1.png)
getComputedStyle() 可以获取该obj所有style,只可以获取不能设置
调用方式getComputedStyle(obj,null)[属性]或者getComputedStyle(obj,null).属性;
兼容:兼容其他浏览器,IE浏览器只兼容ie9以上,
![](https://i-blog.csdnimg.cn/blog_migrate/79ccdc40280083f2dbf9304c9c90a161.png)
获取非行内样式兼容写法:
function getStyle(ele,attr){
if(ele.currentStyle){
return ele.currentStyle[attr] ; //IE使用
}else{
return ele.getComputedStyle[attr]; //moz等其他浏览器使用
}
}
2、事件冒泡与默认事件的兼容及方法说明:
阻止事件冒泡:
阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你调用这个方法的时候,如果点击一个连接,这个连接仍然会被打开,所以一般配合默认事件一起使用。
e.stopPropagation()方法,取消事件冒泡对当前节点无影响
符合w3c标准,适合谷歌火狐等浏览器,仅支持IE9以上版本
![](https://i-blog.csdnimg.cn/blog_migrate/58b76373eb85db1e131b5b67b068bbf8.png)
兼容IE事件对象:
cancelBubble()返回的是一个布尔值,放在if语句里面判断 取消事件冒泡
不符合W3C标准,只支持IE浏览器。
从Chrome 58和Opera 45开始,谷歌和欧朋将此属性设置为false无效。
![](https://i-blog.csdnimg.cn/blog_migrate/32b859f3e399c205c00cdf8c4a9c5ca6.png)
阻止事件冒泡兼容写法
function stopBubble(e){
//判断浏览器
if(e.stopPropagation){
e.stopPropagation(); //moz等浏览器执行
}else{
//不是的话,使用cancelBubble方法
e.cancelBubble = turn; //IE浏览器使用
}
阻止默认事件:
阻止右键菜单,阻止ctrl+c,阻止表单提交
阻止默认事件的方法,调用此方法,连接不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素;
e.preventDefault()
兼容主流浏览器,兼容ie9以上浏览器
![](https://i-blog.csdnimg.cn/blog_migrate/0da4de4b87a7e7c1af0c941386577737.png)
e.returnValue
返回的是布尔值,在IE6以上浏览器可以兼容,在火狐浏览器中不支持
![](https://i-blog.csdnimg.cn/blog_migrate/eb0f13790becfb37232677bb161d6374.png)
阻止默认事件的兼容写法
function stopDefault(e){
if(e.preventDefault){ //moz等浏览器执行
e.preventDefault()
}else{
e.returnValue = false; //IE下执行
}
return false方式阻止冒泡和默认事件
会同时阻止事件冒泡和默认事件,相当于同时调用了event.stopPropagation()和event.preventDefault()
3、事件获取兼容
//IE是把event事件对象作为全局对象window的一个属性;可以使用event或window.event来访问;
//FireFox和Chrome等主流浏览器是通过把【事件对象】作为【事件响应函数】的【参数】进入传入的;
//兼容性的写法示例:
domElement.onclick = function( e ){
var e = e || window.event; //或(||)书写顺序有讲究,不能随意换
}
事件获取兼容的三元表达式写法:
var e = event ? event : event:window.event;
window.event
![](https://i-blog.csdnimg.cn/blog_migrate/6d0e95d729d09f62bc72f08a900dc170.png)
事件源的获取的兼容(事件委托机制)
e.target
e.srcElement
IE浏览器下没有target属性,只有srcElement属性,
FF浏览器则和IE浏览器相反
chrome下同时兼容两个方法
![](https://i-blog.csdnimg.cn/blog_migrate/ce410fb62e590c4268737576898d355d.png)
function foo(event){
var evt = window.event||event;
var targetObj = evt.target||evt.srcElement;
}
事件源的获取三元表达式写法:
var targetobj = event.srcElement? event.srcElement : event.target;
4.事件绑定方式的兼容
DOM绑定事件
0级绑定事件
// obox.onclick = function(){}
删除事件
element.onclick = null;
2级事件绑定(监听式事件绑定)
2级事件绑定:可以重复绑定多个事件,但是存在兼容问题
在IE浏览器中兼容
:
添加事件:obj.attachEvent(event,function)
添加事件:obj.attachEvent(event,function)
删除事件:obj.detachEvent(event,function
)
微软私有方法,火狐和其他浏览器不支持
在IE浏览器中只有冒泡阶段,事件名需要加on;
在其他浏览器兼容:
添加事件:obj.addEventListener(type,listener
,useCapture
)
type:事件的类型比如"click","mouseover"等等。
listener:回调函数
useCapture:用来确定是冒泡还是捕获,默认值是false,当为ture时是冒泡传递
删除事件:obj.removeEventListener(type,listener
)
type:需要删除的事件(事件句柄)
listener:回调函数
![](https://i-blog.csdnimg.cn/blog_migrate/bf9752310e1a67bd2f25dab4aa6a65a3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6b634b8a88984cd8a9900386384bcf8d.png)
事件绑定方式的兼容函数的封装
function addEvent(obj,inci,back){
if(obj.addEventListener){
obj.addEventListener(inci,back);
}else if(obj.attachEvent){
obj.attachEvent("on" + inci,back);
}else{
obj["on"+inci] = back;
}
}
function removeEvent(obj,inci,back){
if(obj.removeEventListener){
obj.removeEventListener(inci,back,false);
}else if(obj.detachEvent){
obj.detachEvent("on" + inci,back);
}else{
obj["on"+inci] = null;
}
}
5.其他一些兼容问题:
滚动条兼容问题解决:
document.documentElement.scrollTop||document.body.scrollTop
网页可视区域兼容
window.innerHeight || document.documentElement.clientHeight
window.innerWidth || document.documentElement.clientWidth
欢迎大家补充,以及错误指正。