常见h5DOM兼容操作 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{100px;height:100px;border: solid 1px black;}
</style>
</head>
<body>
<div ></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{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 {
400px;
height: 400px;
background: red
}
.box2 {
300px;
height: 300px;
background: blue
}
.box3 {
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 {
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 {
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 {
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>