JavaScript 事件模型

来源:互联网 发布:crm客户管理系统源码 编辑:程序博客网 时间:2024/05/11 05:30

在编程中,事件非常类似于打电话。页面上发生了某个操作,会触发了某个事件,我们就可以响应这个事件,对事件做出处理。例如,用户单击页面,按下键盘上的一个键,或者把鼠标指针移过某段文本时,都会发生事件。另一个常用事件是页面的load事件,当页面完全加载到浏览器中时,窗口将引发(或触发)一个通知。
当事件发生时,需要使用事件处理程序(event handler)或监听器(listener),并把它关联到事件发生时要执行的代码上。这就提供了在事件发生时捕获事件并执行相应代码的方式。在代码中加入事件处理程序称为“将代码连接到事件”。

事件类型

Web开发,尤其是涉及JavaScript时,主要是事件驱动的,这表示程序流由事件控制。换言之,JavaScript代码的大部分通常只在事件发生时执行,而且可以监听许多事件。
下面是可以监听和响应的事件类型列表:

  • 鼠标事件:用户用鼠标执行某个操作时,例如移动光标,单击,双击,拖动等,就会发生鼠标事件。
  • 键盘事件:按下或释放键盘上的键时,就会发生键盘事件。这些事件常常与表单一起使用,但每次用户按下或释放一个键时,就会发生键盘事件。
  • 进度事件:这些事件比较一般,在对象的不同阶段发生,例如文档加载时。
  • 表单事件:表单上的某个内容改变时发生。
  • 突变事件:修改DOM节点时发生。
  • 触摸事件:用户轻触感应器时发生。
  • 错误事件:出错时发生。
  • 将代码连接到事件

    JavaScript的内置对象没有事件,而浏览器对象模型(BOM)和文档对象那个模型(DOM)对象有相关的事件。
    可以用三种方式将代码连接到事件:

    • 指定HTML属性
    • 指定对象的特定属性
    • 调用对象的特定方法

    通过HTML属性处理事件

    将事件连接到元素对象很简单,只需要将事件添加到捕获了该事件的元素对象的开始标记上。如下代码所示,点击超链接后,将显示一个警告框,之后超链接才会执行默认的行为,进入href属性定义的页面:

        <a href="http://www.baidu.com" onclick="alert('这是百度')">百度</a>

    在本例中,该事件是<a/>元素定义的a对象的click事件,一旦单击了这个链接,就需要捕获该事件,并连接到代码上。因此,可以在<a>开始标记上添加事件处理程序onclick,作为一个属性,该属性的值设置为事件触发时要执行的代码。
    在元素开始标记上事件处理程序属性中可以返回一个boolean值,来决定是否执行元素默认的行为。如果该属性返回true,则执行元素默认的操作行为,反之则不执行。如下代码所示:

        <a href="http://www.baidu.com" onclick="return linkClick()">百度</a>    <script>        function linkClick() {            alert("是否拦截事件");            return false;        }    </script>

    onclick属性连接到调用linkClick() 函数的代码上,当用户单击超链接时,就执行这个函数。在定义onclick属性时,在函数名前使用return语句,返回了该函数的返回值。由onclick=”return linkClick()”返回的值由JavaScript用来决定是否执行链接的正常操作行为,即进入一个新页面。如果返回true,则继续执行该操作,页面跳转到www.baidu.com。如果返回false,则不执行正常的事件链(即页面跳转),即取消与事件关联的操作。
    注意:并不是所有的对象及其事件都使用返回值,因此有时返回值是多余的。

    某些事件并不直接链接到用户的操作上。例如,window对象的load事件在页面加载时完成,unload事件在页面卸载(用户关闭浏览器,或者转向另一个页面)时触发。window对象的事件处理程序实际上放在<body>开标记中。例如,要为load和unload事件添加事件处理程序:

    <body onload="alert('加载')" onunload="alert('卸载')">

    在元素对象的事件处理程序属性中可以传递该对象给调用的函数,只需要在调用函数中添加一个参数,然后元素对象传递this给这个函数参数。如下代码所示:

    <body>    <img src="Sierra15.jpg" onclick="changeImg(this)">    <img src="Sierra16.jpg" onclick="changeImg(this)">    <script>        var images=[            "Sierra15.jpg",            "Sierra16.jpg",            "Sierra23.jpg",            "Sierra48.jpg",            "Sierra50.jpg"        ];        function changeImg(that) {            var newImgNum=Math.round(Math.random()*4);            that.src=images[newImgNum];        }    </script></body>

    该代码中定义了changeImg()函数,该函数会连接到页面上定义的<img>元素的onclick事件处理程序上。可以将任意多个元素的事件处理程序连接到同一个函数。给HTML元素的属性事件处理程序传入this时,该元素的对应对象就会传入函数。该函数从参数that中获取到img元素使用this传递自身的对象,从而可以访问所单击的img对象。

    除了使用this作为参数传递元素对象给函数外,还可以使用传递Event对象给函数来访问接受事件的元素。Event对象包含关于事件的所有信息,有一个重要的属性target,是触发事件的元素对象。如下所示:

        <a href="http://www.baidu.com" onclick="linkClick(event)">百度</a>    <script>        function linkClick(event) {            alert(event.type);        }    </script>

    这个event变量是特殊的,因为它没有定义,而是一个仅用于事件处理程序的参数,通过HTML属性连接。在事件触发时,它传递当前event对象的引用。可以使用event.type作为事件过滤器,确定发生了何种事件(event.type),哪个HTML元素(event.target)触发了它,这样就可以用不同的方式处理每个事件。

    通过对象属性处理事件

    上述通过指定使用HTML属性事件处理程序的方法并不适用于动态创建的元素(如document.createElement()创建的元素)建立事件处理程序,但可以使用对象的事件处理程序属性来解决。首先需要定义事件发生时执行的函数,然后把对象的事件处理程序属性设置为前面定义的函数,如下 所示:

    <body>    <a id="hrefLink" href="http://www.baidu.com">Clike me</a>    <script>        function linkClick() {            alert("触发事件");            return false;        }        document.getElementById("hrefLink").onclick=linkClick;    </script></body>

    同样可以在事件处理函数中返回一个boolean值,表示是否要执行元素对象的正常操作。使用该方式时浏览器会自动执行事件连接,触发事件,执行事件处理程序时,浏览器会自动给处理函数传递Event对象。

        <script>        function linkClick(event) {            alert("触发事件"+event.type);        }        document.getElementById("hrefLink").onclick=linkClick;    </script>

    删除事件处理程序很简单,只需要将事件处理程序属性赋值为null即可:

    document.getElementById("hrefLink").onclick=null;

    标准事件模型

    前面使用的两种方式来监听事件是非标准的,它们在每个浏览器中都有效,但这个功能仅用于向后兼容,不能保证它们在未来的浏览器版本中也有效。
    DOM标准定义了一个对象EventTarget,其作用是定义一种标准的方式,为目标上的事件添加和删除监听器。DOM中的每个元素节点都是一个EventTarget,还可以动态地为给定元素添加和删除事件监听器。
    DOM标准还描述了一个Event对象,该对象提供了触发事件的元素信息,并允许在脚本中获取该元素。它提供了一组规则,以标准的方式确定何种元素生成事件,生成何种类型的事件,以及何时何地出触发事件。如果要在脚本中使用Event对象,则必须将它作为参数,传入与事件处理程序关联的函数。
    EventTarget对象定义了两个方法来添加和删除事件监听器(EventTarget是一个元素)。可以使用addEventListener()在元素对象上注册事件监听器,使用removeEventListener()在元素对象上移除事件监听器。

    <a id="link" href="http://www.baidu.com">百度</a><script>.    document.getElementById("link").addEventListener("click",function (e) {        alert("click");        e.preventDefault();    });</script>

    addEventListener中包含两个参数,第一个参数是没有前缀”on”的事件名,第二个参数是事件发生时执行的函数,这里使用的是匿名函数,也可以声明一个单独的函数,然后传递这个函数给addEventListener。使用声明好的函数,允许为多个事件监听器重用它。注意在Event对象上调用e.preventDefault方法,这是禁止发生元素的默认操作的标准方式,而不是返回boolean值。

        function changImg(e) {        var target=e.target;        var newImgNum=Math.round(Math.random()*4);        target.src=images[newImgNum];        document.getElementById("img0").removeEventListener("click",changImg);    }    document.getElementById("img0").addEventListener("click",changImg);

    使用声明好的函数,还可以通过removeEventListener()方法来注销事件监听器。删除事件监听器时,必须提供与调用addEventListener()时相同的信息,第一个参数为同名的事件名,第二个参数为传递给addEventListener()第二个参数的同一个函数对象:

    elementObj.removeEventListener("click",elementObjClick);

    使用标准DOM事件模型的另一个优点是可以为一个元素的一个事件注册多个事件监听器,注意多个监听器会按照它们注册的顺序依次执行:

    elementObj.addEventListener("click",handlerOne);elementObj.addEventListener("click",handlerTwo);elementObj.addEventListener("click",handlerThree);

    Event事件数据

    DOM标准事件模型给出了Event对象的几个属性,这些属性提供了事件的相关信息:在哪个元素上发生了事件,发生了什么类型的事件,在何时发生等。这些都是Event对象提供的数据。如下图列出了规范中指定的属性:

    Event对象的属性 说明 bubbles 表示是否允许事件冒泡(即控制权从事件目标开始,沿着层次结构从一个元素向上传递给另一个元素) currentTarget 事件在DOM中传递时,指定事件的当前目标 defaultPrevented 表示在事件上是否调用preventDefault( ) eventPhase 表示事件当前处于事件流的哪个阶段 target 该属性表示引发事件的元素;在DOM事件模型中,文本节点也可能是事件目标 timestamp 表示事件发生的时间 type 表示事件的类型

    DOM标准事件模型中还引入一个MouseEvent对象,专门用来处理鼠标引发的事件。这是非常有用的,因为我们可能需要事件的更详细信息,如指针的位置(像素),或者鼠标来自哪个元素,如下图列出了MouseEvent对象的一些属性。

    Event对象的属性 说明 altKey 表示事件发生时,是否按下Alt键 button 表示按下鼠标的哪一个按钮 clientX 表示事件发生时,鼠标指针在浏览器窗口中的水平坐标 clientY 表示事件发生时,鼠标指针在浏览器窗口中的垂直坐标 ctrlKey 表示事件发生时,是否按下Ctrl键 metaKey 表示事件发生时,是否按下meta键 relatedTarget 用于标识第二个事件目标。对于mouserover事件,该属性表示鼠标指针退出的元素;对于mouseout事件,该属性表示鼠标指针进入的元素 screenX 表示事件发生时,鼠标指针相对于屏幕坐标原点的水平坐标 screenY 表示事件发生时,鼠标指针相对于屏幕坐标原点的垂直坐标 shiftKey 表示事件发生时,是否按下Shift键

    尽管任何事件都可能创建Event对象,但是只有一组选定的事件才能生成MouseEvent对象。如果产生了MouseEvent事件,就可以访问Event和MouseEvent对象的属性。
    对于非鼠标事件,上表中的MouseEvent对象属性不可用,下列的鼠标事件可以创建MouseEvent对象:

    • click事件:当指针位于某个元素或文本上时,单击(按下并释放)鼠标将触发click事件。
    • mousedown事件:当指针位于某个元素或文本上时,按下鼠标将触发mousedown事件。
    • mouseup事件:当指针位于某个元素或文本上时,释放鼠标键将触发mouseup事件。
    • mouseover事件:当指针移入某个元素或文本中时,将触发mouseover事件。
    • mousemove事件:当指针位于某个元素或文本上时,移动指针将触发mousemove事件。
    • mouseout事件:当指针从某个元素或文本上移出时,将触发mouserout事件。

    与MouseEvent不同,当前的DOM规范没有为与键盘相关的事件定义KeyboardEvent对象(但下一个版本DOM level3定义了它)。使用下表列出的属性可以访问与键盘相关的事件:

    KeyboardEvent对象的属性 说明 altKey 表示事件发生时是否按下Alt键 charCode 用于keypress事件,键的Unicode引用号 ctrlKey 表示事件发生时是否按下Ctrl键 keyCode 依赖系统和浏览器的数码,表示按下的键 metaKey 表示事件发生时是否按下meta键 shiftKey 表示事件发生时是否按下shift键
    0 0
    原创粉丝点击