Javascript的DOM中兼容问题以及解决兼容问题的方法
一、获取非行内样式的方法和它的兼容问题及解决方式
方 法 一:getComputedStyle(obox,false)
第一个参数表示要获取的对象,第二个值指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)false也可以。主要针对正常浏览器
方 法 二:Element.currentStyle 在IE浏览器中使用
解决兼容问题的方式:
function getStyle(ele,attr){ if(ele.currentStyle){ return ele.currentStyle[attr]; }else{ return getComputedStyle(ele,false)[attr]; } }
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> #box{width:100px;height:100px;border: solid 1px black;} </style> </head> <body> <div id="box" style="background: red"></div> </body> <script> var obox = document.getElementById("box") // 行内样式;是可以获取和设置的 console.log(obox.style.background);// red // 用style操作获取不了非行内样式 console.log(obox.style.border);// 为空 // 如何获取非行内样式,只能获取不能设置; // Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计 // 算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。 console.log(getComputedStyle(obox,null)); //第一个参数表示要获取的对象,第二个值指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)false也可以。 console.log(getComputedStyle(obox,null).width);//100px; // 由于getComputedStyle()存在兼容,另一个获取方法 // Element.currentStyle可以在ie里用 console.log(obox.currentStyle);//undefined // console.log(obox.currentStyle.width) // 为了解决兼容问题,可以将这两种放进一个封装函数中 function getStyle(ele,attr){ var a = ""; if(ele.currentStyle){ a = ele.currentStyle[attr];//attr是一个变量,变量用中括号 }else { a = getComputedStyle(ele,false)[attr]; } return a; } getStyle(obox,"width") // 简易写法 function getStyle(ele,attr){ if(ele.currentStyle){ return ele.currentStyle[attr];//attr是一个变量,变量用中括号 }else { return getComputedStyle(ele,false)[attr]; } } getStyle(obox,"width") // 这样绝大部分浏览器兼容问题就解决了 </script> </html>
二、获取事件对象的方法和它的兼容问题及解决方式
1.IE中: window.event
2.正常浏览器中: 对象.on事件 = function(event){}
解决兼容问题的方式:
document.onclick = function(eve){ var e = eve || window.event; }
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box{width:100px;height:100px;background: red;} </style> </head> <body> <div class="box"></div> </body> <script> // 如何获取事件对象? // 给事件处理函数一个形参; var obox = document.querySelector(".box") // obox.onclick = function(abc){ // console.log(abc) // } // obox.onclick = function(){ // console.log(window.event) //可以在ie使用; // } // 解决兼容 obox.onclick = function(eve){ var e = eve || window.event; console.log(e);//通过event获得一个对象 } </script> </html>
三、阻止事件冒泡的方法和它的兼容问题以及解决方式
方 法 一:eve.stopPropagation(); 主要针对正常浏览器
方 法 二:eve.cancelBubble = true; 在IE浏览器中使用
解决兼容问题的方式:
function stopBubble(e){ if(e.stopPropagation){ e.stopPropagation(); }else{ e.cancelBubble = true; } }
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box1 { width: 400px; height: 400px; background: red } .box2 { width: 300px; height: 300px; background: blue } .box3 { width: 200px; height: 200px; background: green } </style> </head> <body> <div class="box1"> <div class="box2"> <div class="box3"></div> </div> </div> </body> <script> // 事件冒泡 // 当触发某个元素的某个事件时,它会先触发自己的对应事件,然后,“依次向上”触发所有父级的“相同事件”,如果中间有父级没有“相同事件”,继续向上触发 // 事件流:事件执行顺序我们叫他事件流。 // 事件流中事件冒泡的由来:IE公司认为,如果你面前有个靶子,你的飞镖射中了其中一环,并不仅仅是只对这一环产生了操作,而是对整个靶子都产生了操作。 // 所以,当 最里面 的元素触发了事件的时候,会依次向上触发所有元素的相同事件(从触发事件的元素开始一直向上触发),但是事件冒泡对我们几乎没有任何好处, // 所以我们需要阻止事件冒泡。 //阻止事件冒泡的两种方法 // eve.stopPropagation(); // eve.cancelBubble = true; //兼容IE // 解决兼容问题:封装一个函数 function stopBubble(e){ if(e.stopPropagation){ e.stopPropagation(); }else{ e.cancelBubble = true; } } var obox1 = document.querySelector(".box1"); var obox2 = document.querySelector(".box2"); var obox3 = document.querySelector(".box3"); obox1.onclick = function(eve){ var e = eve || window.event; stopBubble(e); alert("red"); } obox2.onclick = function(eve){ var e = eve || window.event; stopBubble(e); alert("blue"); } obox3.onclick = function(eve){ var e = eve || window.event; stopBubble(e); alert("green"); } </script> </html>
四、键盘事件的兼容问题以及解决方式
解决兼容问题的方式:
var e = eve || window.event; var code = eve.keyCode || window.which;
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box { width: 100px; height: 100px; background: red; position: absolute; left: 0; top: 0; } </style> </head> <body> <div class="box"></div> </body> <script> // 和鼠标事件一样,键盘事件也存在兼容; // var e = eve || window.event; // var code = e.keyCode || e.which; // 案例:通过键盘上下左右,控制页面中的元素位置移动 var obox = document.querySelector("div"); // 这个div并没有焦点;所以: //先创一个事件对象; document.onkeydown = function(eve){ var e = eve || window.event; var code = eve.keyCode || window.which; // 这里通过选择语句中的switch(); switch(code){ // 获取元素与父元素之间的偏移距离;用offsetLeft/offsetTop; case 37 : //左键 obox.style.left = obox.offsetLeft-10 + "px";break; case 38 : //上键 obox.style.top = obox.offsetTop-10 + "px";break; case 39 : //右键 obox.style.left = obox.offsetLeft+10 + "px";break; // 向上向右就是+10; case 40 : //下键 obox.style.top = obox.offsetTop+10 + "px";break; } } </script> </html>
五、阻止默认事件的方法和它的兼容问题以及解决方式
方 法 一:
e.preventDefault();
window.event.returnValue = false;
方 法 二:
在事件处理函数的最后加上 return false;
解决兼容问题的方式:
function stopDefault(e){ if(e.preventDefault){ e.preventDefault() }else{ e.returnValue = false; } }
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box { width: 120px; height: 220px; background: #fff; border: 1px solid #000; position: absolute; left: 0; right: 0; display: none; } .box ul { margin: 0; } </style> </head> <body> <div class="box"> <ul> <li>刷新</li> <li>复制</li> <li>粘贴</li> <li>剪切</li> <li>删除</li> </ul> </div> </body> <script> // 浏览器默认行为; // 默认事件:就是浏览器自己触发的事件。比如:a链接的跳转,form提交时的跳转,鼠标右键菜单。 // 当触发鼠标的右键事件时,会弹出右键菜单,这就是默认事件情况之一; // 如何阻止默认事件两种方法 //一、解决兼容 // e.preventDefault()(); // window.event.returnValue = false; // 二、 // 在事件处理函数的最后加上 return false; // 案例:自定义右键菜单 // oncontextmenu 鼠标点击右键; var obox = document.querySelector(".box"); // 给阻止事件的方法封装为一个函数 function stopDefault(e){ if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } } document.oncontextmenu = function(eve){ var e = eve || window.event; obox.style.display = "block"; // 阻止默认设置 // stopDefault(e); obox.style.left = e.offsetX + "px"; obox.style.top = e.offsetY + "px"; //return false 也可以阻止默认事件:必须函数里的最后一位 return false; } document.onclick = function(){ obox.style.display = "none"; } function stopDefault(e){ if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } } </script> </html>
六、事件监听器
事件触发阶段主要由于事件流:DOM0级事件处理阶段和DOM2级事件处理;
DOM0级事件处理,是一种赋值方式,是被所有浏览器所支持的,简单易懂容易操作;
元素.onclick = function(){}
DOM2级事件处理是所有DOM节点中的方法,可以重复绑定,但是浏览器兼容存在问题;
非IE下:(这里的事件名不带on),第三个参数表示是在捕获阶段还是冒泡阶段。可以重复绑定事件,执行顺序按照绑定顺序来执行。
oDiv.addEventListener('click',fn,false);
oDiv.removeEventListener('click',fn ,false);
IE下:
只有冒泡阶段,所以没有第三个参数;(这里的事件名需要加on)
oDiv.attachEvent();
oDiv.detachEvent() ;
解决兼容问题的方式:
1.封装成对象的方式 var EventUtil={ addHandler:function(DOM,EventType,fn){ if(DOM.addEventListener){ DOM.addEventListener(EventType,fn,false); }else if(DOM.attachEvent){ DOM.attachEvent('on'+EventType,fn) }else{ DOM['on'+EventType]=fn } }, removeHandler:function(DOM,EventType,fn){ if(DOM.removeEventListener){ DOM.removeEventListener(EventType,fn,false) }else if(DOM.detachEvent){ DOM.detachEvent('on'+EventType,fn) }else{ DOM['on'+EventType]=null; } } } 2.封装成两个函数的方式 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; } }
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box { width: 100px; height: 100px; background: red; } </style> </head> <body> <div class="box"></div> </body> <script> var obox = document.querySelector(".box"); // 事件触发阶段主要由于事件流:DOM0级事件处理阶段和DOM2级事件处理; // DOM0级事件处理,是一种赋值方式,是被所有浏览器所支持的,简单易懂容易操作; // 元素.onclick = function(){} // 赋值式绑定 (DOM0级事件处理阶段) // obox.onclick = function(){ // console.log(1); // } // obox.onclick = function(){ // console.log(2); // } // 当你点击元素时,只能获取1,2中的一个值; // 删除赋值式事件绑定; // obox.onclick = null; // 特点:常用,没有兼容,简单 // 监听式绑定(DOM2级事件处理):可以重复绑定; // 非IE下:(这里的事件名不带on),第三个参数表示是在捕获阶段还是冒泡阶段。可以重复绑定事件,执行顺序按照绑定顺序来执行。 // EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上, // 当该对象触发指定的事件时,指定的回调函数就会被执行。 // oDiv.addEventListener('click', fn, false); // 第一个参数表示:表示监听事件类型的 字符串 。 // 第二个参数表示:当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。 // 第三个参数表示:当第三个参数(设为true) 时,沿着DOM树向上冒泡的事件,不会触发listener。当一个元素嵌套了另一个元素, // 并且两个元素都对同一事件注册了一个处理函数时,所发生的事件 冒泡和事件捕获 是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。 // 第三个参数可写可不写; // oDiv.removeEventListener('click', fn, false); // 删除使用 EventTarget.addEventListener() 方法添加的事件。 // IE下: // 只有冒泡阶段, 所以没有第三个参数;(这里的事件名需要加on) // oDiv.attachEvent() ; // oDiv.detachEvent(); // 冒泡:从下往上(从里往外) // 捕获:从上往下(从外往内) // 如何解决兼容问题 // 将对象放入到括号内 // cb表示事件处理函数 function removeEvent(ele,type,cb){ if(ele.removeEventListener){ ele.removeEventListener(type,cb) }else if(ele.detachEvent){ ele.detachEvent("on"+type,cb) }else{ ele["on"+type] = null; } } function addEvent(ele,type,cb){ if(ele.addEventListener){ ele.addEventListener(type,cb) }else if(ele.attachEvent){ ele.attachEvent("on"+type,cb) }else{ ele["on"+type] = cb; } } </script> </html>
七、事件委托中事件源的兼容问题
解决兼容问题的方式:var t = e.target || e.srcElement;
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> ul { background: #ccc } li { padding: 10px 0; margin: 10px 0; background: red } </style> </head> <body> <ul> <li>link1</li> <li abc="l">link2</li> <li abc="l">link3</li> <li abc="l">link4</li> <li>link5</li> </ul> </body> <script> var ali = document.querySelectorAll("ul li"); var oul = document.querySelector("ul") oul.onclick = function(eve){ var e = eve || window.event; var t = e.target || e.srcElement; // 也是一种兼容 if(t.getAttribute("abc") == "l"){ console.log(e.target.innerHTML) } }
</script>
</html>