事件

来源:互联网 发布:2016最好用的优化软件 编辑:程序博客网 时间:2024/04/28 06:05

时间就是文档和浏览器窗口中发生的一些特定交互瞬间。可以使用侦听器来预定事件,以便事件发生时执行相应的代码。

当我们在网页中点击一个按钮,我们点击的是什么?一个按钮?不是的,我们点击的是一个按钮,也点击了按钮的容器元素。

事件流描述的是从页面中接收事件的顺序。在IE中,事件流是事件冒泡,而在Netscape中事件流则是事件捕获。

事件冒泡 即事件开始时由最具体的元素接收,然后逐级向上传播到不为具体的节点。

<!DOCTYPE html><html><head>    <title>Document</title></head><body>    <div id="button">Click</div></body></html>//如果点击了页面中的div元素,那么这个click会这么传播 - <div> - <body> - <html> - document

在我们触发点击事件的时候,点击事件向上传播,在每一级节点上都会发生,直到传播到document对象。所有浏览器都支持事件冒泡,IE5.5会直接跳过html元素,IE9和其他现代浏览器则一直冒泡到window对象

在Netscape中提出的另一种事件流叫做事件捕获。事件捕获的思想是不太具体的节点应该更早接收到事件,而具体的节点应该最后接收到事件,也就是将上面的顺序颠倒过来

在DOM2级事件中,事件流包括三个阶段:事件捕获阶段,处于目标阶段和冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会,然后是实际目标接收到了事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

 - Document - <html> - <body> - <div> - <body> - <html> - <Document>

在DOM流中,实际目标在捕获阶段并不会接收到事件,这意味着在捕获阶段事件从document到html元素再到body元素后就停止了。下一个阶段是处在目标阶段,于是事件在div元素上发生,并在事件处理中被看成冒泡的一个阶段。冒泡阶段发生,事件又传播回文档。即使DOM2级事件明确规范明确要求捕获阶段不会涉及目标事件,但是在IE9及其他主流浏览器都会在捕获阶段触发事件对象上的事件。结果,就是会有两个机会在目标对象上操作事件。

那什么是事件呢,事件就是用户或者浏览器自身执行的某种动作。click,load,mouseover,mouseout 等等,而响应某个事件的函数就叫做事件处理程序。

<input type="button" value="click me" onclick="alert('hello')">

大多数我们使用事件会编写一个函数,当我们触发事件的时候调用这个函数

//script文件中function say(){    alert('hello');}//html中<button onclick="say()">click me</button>

事件处理程序中的代码在执行时有权访问全局作用域中的任何代码。这样指定事件处理程序具有一些独到之处。首先这样会创建一个封装着元素属性值的函数,这个函数中有一个局部变量event,也就是事件对象。

<button onclick="alert(event.type)">click</button>//点击出现click

通过event变量可以直接访问事件对象,你不用自己定义它,也不用从参数列表中读取。在这个函数内部,this值等于事件的目标元素。

<button onclick="alert(this.innerText)">HeyJude</button>//HeyJude

另一个有意思的地方就是他扩展作用域的方式。在这个函数内部,可以像访问局部变量一样访问document及元素本身的成员

function(){    with(document){        with(this){            //元素属性        }    }}

如果当前元素是一个表单输入元素,则作用域还会包括访问表单元素的入口。

//html代码<form>    <input type="text" name="username" value="">    <input type="button" value="click" onclick="alert(username.value)"></form></body><script type="text/javascript">

通过javascript指定事件处理的传统方式就是将一个函数复制给一个事件处理机制程序,程序中的this指向当前元素

var list=document.getElementById("li");list.onclick=function(){    alert("hello,world");}

在DOM2级中定义了两个方法,用于处理指定和删除事件处理程序的操作addEventListener()removeEventListener() 。所有DOM节点都包含这两个方法,他们接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,则在冒泡阶段调用事件处理程序。
注意的是,我们在使用addEventListener注册事件处理程序的时候,如果注册的事件恰好注册到了事件目标上,那么这个事件会处于目标阶段,在目标阶段的事件会触发所有的监听器,而不在乎这个监听器注册时候的useCapture的值,也就是按照我们的注册顺序执行

var button=document.getElementsByTagName("button")[0];button.addEventListener("click",function(){},false);

通过这种方法添加的事件处理程序只能通过removeEventListener()方法来删除他

//html<ul>    <li>1</li>    <li>2</li>    <li>3</li></ul>//scriptvar list=document.getElementsByTagName("li");var ul=document.getElementsByTagName("ul")[0];list[0].addEventListener("click",function(){alert("hello"),false})list[1].addEventListener("click",function(){alert("hi"),false})ul.addEventListener("click",function(){alert("ul")},true)

需要注意的是,通过匿名函数添加的事件处理程序无法被删除,请谨慎使用匿名函数在addEventListener。并且为了兼容性我们通常是使用false添加到冒泡阶段中;在IE中实现了与DOM类似的两个方法:attachEvent detachEvent 这两个方法接收两个相同的参数:事件处理程序名称和事件处理函数,由于IE8以及早起版本只支持时间冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

var btn=document.getElementById("btn");btn.attachEvent("onclick",function(){alert('hello,world')});

attachEvent的第一个参数是”onclick”,而非DOM的addEventListener()的”click”,在IE使用attachEvent 与使用DOM方法的主要区别在于事件处理程序的作用域。事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局中运行,故this等于window。

var btn=document.getElementById("btn");btn.attachEvent("onclick",function(){alert(this===window)});//true

在编写跨浏览器代码时,我们要时刻记住this的指向。

addEventListener() 类似,attachEvent()方法也可以用来为一个元素添加多个事件处理程序,但是这些并不是以添加他们的顺序执行的,而是以相反的顺序被触发的。

删除 IE中的事件处理程序attachEvent()我们可以通过detachEvent()来移除,条件是必须使用相同的参数,与DOM方法一样,这也意味着添加匿名函数不能被移除。

原创粉丝点击