首页>前端教程>JavaScript教程

DOM基础6:event.stopPropagation与event.preventDefault的区别和兼容性

event : 事件对象 , 当一个事件发生的时候,和当前这个对象发生的这个事件有关的一些详细的信息都会被临时保存到一个指定地方-event对象,供我们在需要的时候调用。这个有点像飞机的黑匣子。

事件对象必须在一个事件调用的函数里面使用才有内容。

事件函数:事件调用的函数,一个函数是不是事件函数,不在定义的时候决定,而是取决于被调用的时候。

如果一个函数是被事件调用的,那么这个函数定义的第一个参数就是事件对象。

function fn1(ev) {
    //alert( event );
    //alert( ev );
    var ev = ev || event;
    //alert(ev);
    
    for ( var attr in ev ) {
        console.log( attr + ' = ' + ev[attr] );
    }
    
    alert(ev.clientX);
}

//fn1();    //不是事件调用的函数
document.onclick = fn1; //是事件调用的函数,所以event有内容

一、Event事件对象的兼容性

事件对象本身也是有兼容性的。

W3C标准规定,事件是作为函数的参数传入的,例如:

<div id="div1">点击我将获得鼠标坐标</p>
document.getElementById("div1").onclick=function(ev){
    alert(ev.clientX);
}

当在元素上点击时,弹出警告框,内容为鼠标在可视区上的横坐标。这里函数传入的参数ev,就是事件对象,浏览器会实时跟踪用户的行为,如ev.screenX、ev.screenY、ev.clientX、ev.clientY…

这种做法在FireFox、Chrome、Safari等遵循W3C规范的浏览器下是没有问题的,唯独在IE非标准浏览器,IE8及以下是行不通的, IE8等非标准浏览器采用了一种非标准的方式,将事件作为window对象的event属性:window.event、window.event.screenX…

所以为了兼容性,常常看到这种写法:

<div id="div1">点击我将获得鼠标坐标</p>
document.getElementById("div1").onclick=function(ev){
    var ev = ev || event;
    alert(ev.clientX);
}

注意:不要将var ev=ev | |event; 写成 var ev=event || ev; ,这在FireFox下会提示错误,FireFox无法处理未声明未赋值的变量event。

或运算(||)返回的并不只是true或者false,而是返回第一个不为false的变量的值,例如: 

var a=5||6; //a=5 
var b=0||5; //b=5 
var c=false || "www.itxueyuan.com"; //c="www.itxueyuan.com" 
var ev=ev || event; //ev为用户事件

与运算(&&)返回第一个不为true的变量的值; 

在处理浏览器兼容问题的时候,尽量不要去判断浏览器,那将会为向后兼容带来风险,或许某个升级的版本开始遵循W3C标准,我们之前写的代码在该版本上就会产生错误,得不到预想结果。

比如IE9就支持将事件作为参数传入。

如果不兼容IE8等非标准浏览器,就直接用标准的方法,将事件作为参数传入。

二、阻止默认行为

比如  a的href,链接跳转就是超链接的默认行为。

  href为空,会自动刷新页面

  href为#,  锚点跳转

  href为JavaScript:;     阻止默认行为的发生    

 (以上是a标签阻止浏览器的默认行为,但是别的对象也会有默认行为,比如表单等)

W3C规定标准的方法是:

event.preventDefault();

但是IE8等非标准不支持这个方法,它有自己的属性returnValue,所以兼容性的写法是:

if (event.preventDefault){
event.preventDefault();
}
else{
event.returnValue=false;
}

也可以简写成: 

event.preventDefault ? event.preventDefault() : (event.returnValue = false);

三、阻止事件冒泡

事件冒泡机制 : 当一个元素接收到事件的时候,会把它接收到的所有事件传播给他的父级,一直到顶层window。

标准浏览器:

event.stopPropagation();

IE8等非标准浏览器:

event.cancelBubble=true;

不过关于这个cancelBubble的写法,后来标准浏览器也支持了。

兼容性写法:

if (event.stopPropagation){
    event.stopPropagation();
}
else{
    event.cancelBubble=true;
}

或者简写成:

event.stopPropagation? event.stopPropagation():(event.cancelBubble=true);

比如最典型的案例,点击按钮显示一个层,点击层或者文档空白区域也可以关闭层。

var oBtn = document.getElementById('btn');
var oDiv = document.getElementById('div1');

oBtn.onclick = function(ev) {
    var ev = ev || event;
        
    ev.cancelBubble = true;//阻止当前对象的当前事件的冒泡
        
    oDiv.style.display = 'block';
    }
 document.onclick = function() {
    /*setTimeout(function() {
         oDiv.style.display = 'none';
     }, 1000);*/
        
        oDiv.style.display = 'none';
    }

或者利用事件冒泡把事件都写在父级上,减少代码,这个叫事件委托。

比如网页侧边的“分享到”,或者“个人购物车”信息等,鼠标经过“分享到”,整个模块显示,移开,整个模块隐藏。

<style>
#div1 {width: 100px; height: 200px; background: red; position: absolute; left: -100px; top: 100px;}
#div2 {width: 30px; height: 60px; position: absolute; right: -30px; top: 70px; background: black; color: white; text-align: center;}
</style>

<div id="div1">
    <div id="div2">分享到</div>
</div>

<script>   
    var oDiv = document.getElementById('div1');
    
    oDiv.onmouseover = function() {
        this.style.left = '0px';
    }
    
    oDiv.onmouseout = function() {
        this.style.left = '-100px';
    }   
</script>

点赞


1
保存到:

相关文章

发表评论:

◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。

Top