js中有很多兼容问题,今天先来讨论一些常用的关于低版本IE的兼容。(基本上都是为了兼容IE8一下的)
一、事件对象的兼容问题(event)
比如想要获取鼠标坐标时候需用到event,在高级浏览器中会主动传递该参数,但是在IE8及以下浏览器中,将event放在了window.event属性下,此时用逻辑短路即可轻松解决
btn.onclick=function(ev){
var e=ev||window.event;
console.log(e);
}
二、事件监听绑定和移除的兼容问题(绑定:addEventListener和IE:attachEvent,移除:removeEventListener和IE:detachchEvent)
事件绑定的方式分为两种DOM0级和DOM2级,DOM0级没有兼容性问题,但是不能同时绑定多个事件因为会覆盖,DOM2是事件监听绑定事件可以同时绑定多个事件不会覆盖但是IE8一下却不支持,它有自己的绑定方式:attachEvent,这时候就要考虑兼容了。
我们可以封装一个兼容写法添加事件监听和移除事件监听的方法:
/**
* 添加事件监听
* @param ele <DOMobject> 添加事件的DOM元素
* @param type <string> 事件类型(不带on)
* @param fn <function> 事件处理函数
* @param [isCapture] <boolean>可选参数,是否捕获, true代表捕获,false代表冒泡,默认为false
*/
function on(ele,type,fn,isCapture){
if(isCapture===undefined)isCapture=false;
if(ele.attachEvent){
ele.attachEvent("on"+type,fn);
}else{
ele.addEventListener(type,fn,isCapture)
}
}
/**
* 移除事件监听
* @param ele <DOMobject> 添加事件的DOM元素
* @param type <string> 事件类型(不带on)
* @param fn <function> 事件处理函数
* @param [isCapture] <boolean>可选参数,是否捕获, true代表捕获,false代表冒泡,默认为false
*/
function off(ele,type,fn,isCapture){
if(isCapture===undefined)isCapture=false;
if(ele.detachchEvent){
ele.detachchEvent("on"+type,fn);
}else{
ele.removeEventListener(type,fn,isCapture)
}
}
//使用方法
<button id="btn">取消box事件</button>
<div id="box">box</div>
<script src="utils.js"></script>
<script>
//上面引入了外部封装好的添加和移除监听方法在utils.js中
var btn=document.querySelector("#btn");
var box=document.querySelector("#box");
function foo(){
//放到函数中是为了能添加和移除是同一个事件,只需要拿到foo
console.log("我是box事件")
}
on(box,"click",foo);//添加box事件
on(btn,"click",function(){
//btn点击时移除box事件
off(box,"click",foo);
});
</script>
三、获取滚动条高度的兼容问题(scrollTop)
window.onscroll=function(){
var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
console.log(scrollTop);
}
四、获取键盘事件的键盘码的兼容问题(keyCode和IE:which)
document.onkeydown=function(ev){
var e=ev||window.event;
var keyCode=e.keyCode||e.which;
console.log(keyCode);
}
五、事件委托精确获取目标元素的兼容问题(target和IE:srcElement)
btn.onclick=function(ev){
var e = ev || window.event;
var target=e.target||e.srcElement;
console.log(target);
}
六、阻止事件的默认行为的兼容问题(preventDefault和IE:returnValue)
默认行为是浏览器之中非常重要的构成之一,比如标签类的超链接跳转、form表单提交、浏览器行为的右键菜单、鼠标按下文字选中等都属于浏览器的默认行为,我们用下面的方法阻止它们。但是我们不能随意的去禁止全部的默认事件;
<a href="javascript:void(0)" >点击跳转到百度</a>
<form action="javascript:void(0)" >
<input type="text">
<button id="link">表单里面的button</button>
</form>
document.oncontextmenu = function( ev ){
var e = ev || window.event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
//return false也可以阻止默认事件但是适合后面没有其他逻辑代码,否则会终止函数执行
}
}
七、阻止事件冒泡的兼容问题(stopPropagation和IE:cancelBubble)
document.onclick = function( ev ){
var e = ev || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true;
}
}
八、获取非行间CSS样式的兼容性问题(getComputedStyle和IE:currentStyle)
/**
* 获取元素最终样式值
* @param obj <DOMobject> 要获取属性的元素对象
* @param attr <string> 样式名称
* @return <string> 获取到的样式值
*/
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr]
}
}
//使用方法
var box=document.querySelector(".box");
var width=getStyle(box,"width");
console.log(width);
以上内容全部由自己整理,暂时想到的就这些,如果有小伙伴发现有问题或者有其他更好方法,欢迎评论区一起讨论学习。