浅谈事件监听

Posted tian-yy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈事件监听相关的知识,希望对你有一定的参考价值。

自从学了事件监听之后,觉得他真是个好东西~~,为什么呢?

首先说下他的好处:第一点:他可以实现对未来元素事件的绑定【?未来元素:就是在绑定事件时,页面上还不存在的元素】;第二点:减少事件绑定,提高性能【我们知道前端主要是解决性能优化和兼容问题的,所有这个就挺重要了】

下面来捋一捋事件监听一个比较全面的见解?

1、关于事件

事件分为DOM 0级事件和Dom 2级事件,DOM2级事件也叫做事件监听。DOM 0级事件的缺点是如果事件相同 后者的事件会覆盖前者的事件,DOM2级事件可以解决这个问题

document.onclick = function(){
    alert(1);
}
document.onclick = function(){
   alert(2);
}
//只会执行第二个函数    弹出2

2DOM2级事件的方法

 

 主流浏览器: addEventListener()    【有三个参数】

 

        参数1:事件类型  不需要加on   

        参数2:回调函数名称 (函数需要单独写在外面)    

        参数3:布尔值  true代表捕获   false代表冒泡

       解绑事件方法:removeEventListener()    

首先写两个方法:
function a(){
    alert(1)
}
function b(){
    alert(2)
}
document.addEventListener("click",a);
document.addEventListener("click",b);     //点击后先执行第一个函数,再执行第二个函数
document.removeEventListener("click",a)   //不在执行a()这个函数

IE浏览器下用:attachEvent()    【有两个参数】

        参数1:事件类型  需要加on

        参数2:回调函数名称(函数需要单独写在外面)    

       解绑事件方法:detachEvent()

function a(){
    alert(1)
}
function b(){
    alert(2)
}
document.attachEvent("onclick",a);
document.attachEvent("onclick",b);//点击后先执行第二个函数,再执行第一个函数
document.detachEvent("onclick",a)//不在执行a()这个函数

3、事件流、事件冒泡、事件捕获

        当一个html元素产生一个事件时,该事件会在元素节点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播的过程叫做DOM事件流

        元素触发事件时,事件的传播过程称为事件流,过程分为捕获和冒泡两种

        冒泡事件:微软提出的   事件由子元素传递到父元素的过程,叫做冒泡

举个栗子:

HTML布局如下:
<!
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> #box{width:200px;height:200px;background:#ff3;} #innerBox{width:100px;height:100px;background:blue;} </style> </head> <body> <div id="box"> <div id="innerBox"></div> </div> </body> </html>

Js代码如下:

var box=document.getElementById("box");
var innerBox=document.getElementById("innerBox");
document.addEventListener("click",function(){
alert("document-------冒泡");
},false);
document.body.addEventListener("click",function(){
alert("body-------冒泡");
},false);
box.addEventListener("click",function(){
alert("box-------冒泡");
},false);
innerBox.addEventListener("click",function(){
alert("innerBox-------冒泡");
},false);

  点击innerBox后:   

    执行的顺序是innerBox==box==body===document

    代码输出顺序是:innerBox-------冒泡=====box-------冒泡====body-------冒泡====document-------冒泡

  如果点击box的话   

    执行的顺序是box==body===document

    代码输出顺序是:box-------冒泡====body-------冒泡====document-------冒泡

捕获事件:网景提出的   事件由父元素到子元素传递的过程,叫做事件捕获

Js代码如下:

var box=document.getElementById("box");
var innerBox=document.getElementById("innerBox");
document.addEventListener("click",function(){
alert("document-------捕获");
},true);
document.body.addEventListener("click",function(){
alert("body-------捕获");
},true);
box.addEventListener("click",function(){
alert("box-------捕获");
},true);
innerBox.addEventListener("click",function(){
alert("innerBox-------捕获");
},true);

  点击innerBox后   

    执行的顺序是document==body==box===innerBox  

    代码输出顺序是:document-------捕获=====body-------捕获====box-------捕获====innerBox-------捕获

  如果点击box的话   

    执行的顺序是:document==body==box    

    代码输出顺序是:document-------捕获=====body-------捕获====box-------捕获

以下两个情况值得注意一下:

  1、当事件冒泡和捕获同时执行的时候,是什么顺序?

  Js代码如下:

document.addEventListener("click",function(){
    alert("document-------捕获");
},true);
document.body.addEventListener("click",function(){
    alert("body-------捕获");
},true);
box.addEventListener("click",function(){
    alert("box-------捕获");
},true);
innerBox.addEventListener("click",function(){
    alert("innerBox-------捕获");
},true);
document.addEventListener("click",function(){
    alert("document-------冒泡");
},false);
document.body.addEventListener("click",function(){
    alert("body-------冒泡");
},false);
box.addEventListener("click",function(){
    alert("box-------冒泡");
},false);
innerBox.addEventListener("click",function(){
    alert("innerBox-------冒泡");
},false);

  如果点击innerBox的话:   

    代码输出顺序是:document-------捕获=====body-------捕获====box-------捕获====innerBox-------捕获innerBox-------冒泡=====box-------冒泡====body-------冒泡====document-------冒泡

也就是说当事件冒泡和捕获同时执行的时候执行顺序是:先执行捕获后执行冒泡   

  2、当事件冒泡和捕获同时执行的时候  冒泡事件和捕获事件到最底层的时候顺序发生改变的话:

Js代码如下:

document.addEventListener("click",function(){
    alert("document-------捕获");
},true);
document.body.addEventListener("click",function(){
    alert("body-------捕获");
},true);
box.addEventListener("click",function(){
    alert("box-------捕获");
},true);
innerBox.addEventListener("click",function(){
    alert("innerBox-------冒泡");
},false);
innerBox.addEventListener("click",function(){
    alert("innerBox-------捕获");
},true);
document.addEventListener("click",function(){
    alert("document-------冒泡");
},false);
document.body.addEventListener("click",function(){
    alert("body-------冒泡");
},false);
box.addEventListener("click",function(){
    alert("box-------冒泡");
},false);

  点击innerBox后   

    代码输出顺序是document-------捕获=====body-------捕获====box-------捕获====innerBox-------冒泡innerBox-------捕获=====box-------冒泡====body-------冒泡====document-------冒泡

也就是说冒泡事件和捕获事件到最底层的时候如果顺序发生改变的话:到最底层的时候是顺序执行

4IE与火狐的事件机制区别?

        事件处理机制:IE是事件冒泡、火狐是 事件捕获;

5、事件代理/事件委托

  利用冒泡机制,将子元素的事件委托给父元素去监听(给父元素添加事件),当子元素触发事件时,事件冒泡到父级如果希望指定的子元素才能触发事件,可以通过事件对象(event)获得事件源(target),然后通过条件判断是不是期望的子元素,如果是的话,执行事件,否则不执行

下面举个小栗子简单介绍一下:

HTML结构:
<!
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> a{text-decoration: none;padding:0 5px;} table td{height:24px;line-height:24px;} </style> </head> <body> <button id="btn">添加</button> <table border="1" id="tab"> <tr> <td>333</td> <td><a href="##">查看</a><a href="##" class="delbtn">删除</a></td> </tr> </table> </body> </html>
JS代码:
<script>
var btn=document.getElementById("btn");
var tab=document.getElementById("tab");
var str="";
//现在想要做的效果是  每次点击添加按钮都会在table里面添加一行
//如果点击删除   则会删除table里的一整行
btn.onclick=function(){            //给添加按钮 添加点击事件
    str=‘<tr><td>333</td><td><a href="##">查看</a><a href="##" class="delbtn">删除</a></td></tr>‘;
    tab.innerHTML+=str;        //将内容添加到table里面
}
tab.onclick=function(e){    //给父级添加事件
    var e=e||event;        //事件对象兼容性问题
    var target=e.target||e.srcElement;    //事件源target  兼容性问题
    if(target.tagName=="A" && target.className=="delbtn"){    //条件判断找到子元素【删除按钮】
        target.parentNode.parentNode.remove();
    }    
}
</script>

 效果图如下:

技术分享图片

6、如何找到事件源

     var target = e.target || e.srcElement

      其中: tagName能找到事件源的元素名    className 能找到事件源的类名





























以上是关于浅谈事件监听的主要内容,如果未能解决你的问题,请参考以下文章

浅谈事件监听

在同一个片段中实现多个事件监听器 - Android

JavaFX窗口拖动

c# 获取移动硬盘信息监听移动设备的弹出与插入事件

js 温故而知新 webkitTransitionEnd 监听Transition动画结束事件

浅谈 selectpoll 和 epoll