JavaScript事件处理

处理事件的四种方式:

一.HTML事件处理程序

<input type="button" onclick="showMessage()">

缺点:

1.用户触发事件时,有可能并没有加载完成,会报错(例如上面的showMessage()函数如果在后面才加载到)

解决方法是用try,catch封装好,就不会报错

<input type="button" onclick="try{showMessage();}catch(ex){}">

2.不同浏览器对这种方式的解析略有差异

3.HTML和JavaScript耦合,如果修改要同时改两个地方

 

二.DOM0级事件处理程序(在冒泡阶段处理)

document.getElementById('btn').onclick=function(){
alert(1);
}

缺点:

1.在执行到这段代码前,点击btn是无反应的。

2.只能添加一个事件

删除DOM0级事件的方法:

btn.onclick=null;

 

三.DOM2级事件处理程序(自定义冒泡还是捕获阶段处理)(IE9及以上和现代的浏览器都支持)

document.getElementById('btn').addEventListener("click",function(){
 alert(this);
},false)

注意是click而不是onclick,只有DOM2级和其他的不同,第三个参数默认是false,冒泡

this指向当前的元素

如果同一按钮绑定多个事件,如下,会按照代码顺序执行,先弹出1,再弹出2

document.getElementById('btn').addEventListener("click",function(){
alert(1);
},false)
document.getElementById('btn').addEventListener("click",function(){
 alert(2);
},false)

删除DOM2级事件的方法:removeEventListener()

要与addEventListener()时的参数一致,并且如果绑定的是匿名函数,是无法解除绑定的,因为绑定与解绑的匿名函数是两个函数。

 

四.IE事件处理程序(只有冒泡,没有捕获)(IE8及以下)

document.getElementById('btn').attachEvent("onclick",function(){
alert(this);
})

这里是onclick

this指向window

如果同一按钮绑定多个事件,如下,会按照相反的顺序执行,先弹出2,再弹出1

document.getElementById('btn').attachEvent("onclick",function(){
alert(1);
})
document.getElementById('btn').attachEvent("onclick",function(){
 alert(2);
})

删除IE事件的方法:detachEvent()

要与attachEvent()时的参数一致,并且如果绑定的是匿名函数,是无法解除绑定的,因为绑定与解绑的匿名函数是两个函数。

 

两种事件对象:

1.常见DOM事件对象:

event.type   事件类型

event.eventPhase   事件所处阶段,1表示捕获2表示目标3表示冒泡

event.currentTarget   当前处理的元素,永远等于this

event.target   最终想要处理的目标

event.preventDefault()  取消默认行为(前提是cancelable属性为true)

event.stopPropagation()  停止事件传播(前提是bubbles属性为true)

event.stopImmediatePropagation() 停止事件传播,且自身绑定的后续事件也不再执行

2.IE事件对象:(当使用DOM0级处理时,匿名函数不能传参数event,而要在里面使用window.event

event.type 事件类型

event.srcElement  最终想要处理的目标

event.returnValue 默认值true,改为false就取消默认行为

event.cancelBubble 默认值false,改为true就取消事件冒泡

 

事件委托:

为什么要委托:

1.每个函数都是一个对象,占用内存

2.每次绑定事件都访问DOM,访问DOM是十分耗时的

3.如果不委托,元素呈现,有时候还没有添加事件

 DOM2级委托:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<ul id="myLinks">
  <li id="doSomething">11111</li>
  <li id="goSomewhere">22222</li>
  <li id="sayHi">33333</li>
</ul>
<script>
var list = document.getElementById("myLinks");
list.addEventListener("click",function(event){
  switch(event.target.id){
    case "doSomething":
      alert(1);
       break;
    case "goSomewhere":
      alert(2);
      break;
    case "sayHi":
      alert(3);
      break;
  }
},false);
</script>
</body>
</html>

IE委托:

list.attachEvent("onclick",function(event){
  switch(event.srcElement.id){
    //...
  }
});

 

其他:

在移除带有事件的元素之前,记得要删除对应的事件,不然内存会一直保留(可以在页面卸载前调用onunload事件)

删除事件的另一个用途是阻止冒泡

一般把目标阶段看做冒泡阶段的一部分

一般都在冒泡中处理事件


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
div 
{
    background-colorcoral;
    border1px solid;
    padding50px;
}
</style>
</head>
<body>

<p>该实例演示了在添加事件监听时冒泡与捕获阶段的不同。</p>
<div id="myDiv">
    <p id="myP">点击该段落, 我是冒泡</p>
</div><br>
<div id="myDiv2">
    <p id="myP2">点击该段落, 我是捕获</p>
</div>
<script>
document.getElementById("myP").addEventListener("click"function() {
    alert("你点击了 P 元素!");
}); //任意true或false,因为冒泡还是捕获在这里效果都一样
document.getElementById("myDiv").addEventListener("click"function(){
    alert("你点击了 DIV 元素!");
},false); //先执行里面的p,然后再冒泡到外层DIV

document.getElementById("myP2").addEventListener("click"function() {
    alert("你点击了 P2 元素!");
}); //任意true或false,因为冒泡还是捕获在这里效果都是一样
document.getElementById("myDiv2").addEventListener("click"function() {
    alert("你点击了 DIV2 元素!");
}, true);//立刻捕获外层DIV,然后再执行里面的P

//true表示立刻执行,false则延迟
</script>
</body>
</html>

 

posted @ 2017-03-17 19:25  森森森shen  阅读(241)  评论(0编辑  收藏  举报