`

JavaScript中的事件模型详解

阅读更多

1.javascript中为元素添加事件处理程序的方法

有以下几种方式,可以为javascript元素添加事件处理程序

 

(1) 直接将事件处理代码写在html中

(2) 定义一个函数,赋值给html元素的onXXX属性

(3) 使用element.onXXX方式

 以上三种方式,请看下面代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk"    />
<title>添加事件的方法</title>
<style>
     div {border:1px  solid blue;margin:10px;}
     div#divGrandpa {padding:10px;background-color:#aaaaaa;}
     div#divFather {padding:10px;background-color:#bbbbbb;}
     div#divSon {padding:10px;background-color:#cccccc;}
</style>



</head>
 <body>
<div id="divGrandpa" style="width:500px;height:20px;" onclick="alert('直接将事件处理代码写在html中');">(1) 直接将事件处理代码写在html中 </div>

<div id="divFather" style="width:500px;height:20px;" onclick="clk()" >(2) 定义一个函数,赋值给html元素的onXXX属性 </div>

<div id="divSon" style="width:500px;height:20px;" >(3) 使用element.onXXX方式 </div>

</div>

</body>
<script>
 function clk()
 {
  alert('定义一个函数,赋值给html元素的onXXX属性'); 
 }
 
 function clk1()
 {
  alert('使用element.onXXX方式'); 
 }
 
 var clkEle = document.getElementById('divSon'); 
 //这种方式,必须将本行代码放到上面的html代码<div id="divSon" ...>后面,
 //否则导致找不到divSon,返回null
 clkEle.onclick = clk1;
</script>
</html>

 (4) 使用addEventListener或attachEvent

 

这是目前推荐的方式,较前两种方式功能更为强大,可以为元素添加多个事件handler,

支持事件冒泡或捕获,前三种方式默认都是冒泡。

IE6/7/8仍然没有遵循标准而使用了自己专有的attachEvent,且不支持事件捕获。

注意attachEvent的第一个参数需要加上个"on",比如click事件时,传递参数需要是on+click=onclick

addEventListener第三个参数为false表示事件冒泡,true

attachEvent没有第三个参数,默认就是冒泡,没有捕获。

这种方式代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk"    />
<title>浏览器事件机制——冒泡处理</title>
<style>
     div {border:1px  solid blue;}
     div#divGrandpa {padding:40px;background-color:#f00;}
     div#divFather {padding:40px;background-color:#0f0;}
     div#divSon {padding:40px;background-color:#00f;}
</style>
</head>
 <body>
<div id="divGrandpa" style="width:300px;height:200px;" > I am Grandpa
       <div id="divFather" style="width:200px;height:120px;" > I am father
            <div id="divSon" style="width:100px;height:40px;" >
				点击我 I am son
            </div>
       </div>
</div>
<script>
    function showSon() 
    {
        alert("I am son");
    }
    
    function showFather() 
    {
        alert("I am father");
    }
    
    function showGrandpa() 
    {
        alert("I am Grandpa");
    }
    
    var grandpa = document.getElementById("divGrandpa");
    var father = document.getElementById("divFather");
    var son = document.getElementById("divSon");
    
    if(window.addEventListener)
    {
        grandpa.addEventListener("click", showGrandpa, true);
        father.addEventListener("click", showFather, true);
        son.addEventListener("click", showSon, true);
    }
    else if (window.attachEvent)
    {
        grandpa.attachEvent("onclick", showGrandpa);
        father.attachEvent("onclick", showFather);
        son.attachEvent("onclick", showSon);
    }
</script>    
</body>
</html>

 

2. 事件模型与事件传播

 

  javascript的事件模型可以分为2个级别DOM0,DOM1,DOM2

  (参考:http://www.trans4fun.org/2011/12/%E3%80%90javascript%E4%BA%8B%E4%BB%B6%E7%B3%BB%E5%88%97%E3%80%91dom%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6%E7%AE%80%E6%98%8E%E6%95%99%E7%A8%8B/)

  注:这里DOM1级别的似乎有误,没有DOM1级别事件.

  注:似乎有DOM3了,但是貌似跟事件关系不大,可参考http://blog.sina.com.cn/s/blog_825442790101354v.html

  

  

  前面说的添加时间处理程序方式(1)(2)(3)中处理方式就是DOM0级别的,

  

  方式(3)的好处是将JavaScript和HTML分离开来。

  它通过给HTML元素设置一个属性,该属性是一个回调函数来实现事件的注册。

  然而,这种方式给一个元素的同一事件只允许一个处理器。

  

  方式(4)是DOM级别2,对于DOM级别2的事件最大的好处就是一个事件可以注册许多处理器。

  不仅如此,你还可以指定处理器是在捕获阶段还是冒泡阶段被触发(

  通过设置”addEventListener()”函数的第三个参数来指定 – true表示在捕获阶段,false表示在冒泡阶段)

  

  (注:没有DOM1级的事件:DOM级别1于1998年10月1日成为W3C推荐标准。

  1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。

  参考:http://blog.ueder.info/333.html)

  

  事件传播的过程详解:

  (1)DOM0级的事件模型中,浏览器把时间分派给发生事件的文档元素,那个对象具有适合的时间句柄,就运行这个句柄.

  除此之外,不用执行其他操作.(摘自JavaScript权威指南,犀牛书第5版400页.)

  实际测试发现,DOM0级别的方式定义的事件,默认是冒泡的.

  比如下面的代码:

  在div标签的onclick的onclick属性中指定事件处理函数.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk"    />
<title>浏览器事件机制——冒泡处理</title>
<style>
     div {border:1px  solid blue;}
     div#divGrandpa {padding:40px;background-color:#f00;}
     div#divFather {padding:40px;background-color:#0f0;}
     div#divSon {padding:40px;background-color:#00f;}
</style>
</head>
 <body>
<div id="divGrandpa" style="width:300px;height:200px;" onclick="showGrandpa();" > I am Grandpa
       <div id="divFather" style="width:200px;height:120px;" onclick="showFather();"> I am father
            <div id="divSon" style="width:100px;height:40px;" onclick="showSon();" >
				点击我 I am son
            </div>
       </div>
</div>
<script>
    function showSon() 
    {
        alert("I am son");
    }
    
    function showFather() 
    {
        alert("I am father");
    }
    
    function showGrandpa() 
    {
        alert("I am Grandpa");
    }
</script>    
</body>
</html>
 界面显示如下图:

 



 当点击蓝色部分(son)时,依次触发son,father,grandpa的div的onclick事件,

  可见这个事件传播过程中,事件对象是向上冒泡的.

  这个过程可分解为:

   

  鼠标单击 -> 浏览器生成单击事件 -> 浏览器把单击事件分派给son(div) -> div(son)执行单击处理函数 ->

  事件对象往上传播(即往document对象传播,往body标签方向传播) -> 传播到 father,执行father的click事件处理函数 ->

  事件对象传播到grandpa,执行grandpa的click事件处理函数.

  

  (2)DOM2级的事件模型中,事件的传播分三个阶段:

  a.事件捕捉阶段,事件对象沿着document一直传播到发生事件的那个对象(即文档的目标节点,比如id为son的div),这个过程叫事件捕获.

  b.事件到达目标节点,如果目标节点指定了事件处理函数,则执行这个函数

  c.事件自目标节点向上,沿着a相反的方向再次传播到document对象,这个过程叫做事件冒泡.

  

  使用addEventListener或attachEvent方式注册的事件处理函数,就是这种DOM2级的事件处理函数.

  

  这里有两个函数是因为addEventListener是标准浏览器中的函数,而attachEvent是IE专用的,不是标准浏览器函数.

  

  使用addEventListener方式注册事件处理函数后,

  在事件传播过程中的a,b,c三个阶段中经过的节点都有可能执行该节点注册的事件处理函数,比如在过程a中,对于单击事件来说,

  如果目标节点的任何一个祖先节点注册了单击事件处理函数,则在过程a中就有机会执行这个祖先节点的

  单击事件处理函数.

  

  addEventListener函数调用方式如下:

  grandpa.addEventListener("click", showGrandpa, true);第一个参数是事件名称,第二个参数是事件处理函数名,

  第三个参数为true表示在事件捕获阶段可以执行这个事件处理函数,为false表示不在事件捕获阶段执行该事件处理函数,

  而是在事件冒泡阶段执行时间处理函数(这也是默认的方式,DOM0级别事件处理方式)

  因为第三个参数要么为true要么为false,所以使用addEventListener注册的事件处理函数要么在捕获阶段执行(第三个参数=true),

  要么在冒泡阶段执行(第三个参数=false),

  addEventListener注册的事件处理函数 不会 同时在 捕获和冒泡阶段执行.

  

  attachEvent方式注册事件处理函数,是IE专用的,非标准.事件传播过程只有b和c,即没有事件捕获过程.

  因为attachEvent注册的事件处理函数只在冒泡阶段执行,所以这个函数没有第三个参数.

  调用方式为:grandpa.attachEvent("onclick", showGrandpa);

  需要注意的是,第一个参数,需要在事件名称前面加上on.

3. 事件对象 

   

   在执行监听函数时,会传入一个event对象,其实有一些常用的属性我们会经常用到:

 

type:

 

 发生事件的类型,如click , mouseover, mouseout等

 

target:

 

 发生事件的节点可能与currentTarget不同

 

currentTarget:

 

 正在处理事件的节点,如果在capturing阶段和冒泡阶段处理事件,这个属性就与target属性不同。在事件监听函数中应该用这个属性而不是this

 

stopPropagation():

 

 可以阻止事件从当前正在处理他的节点传播

 

preventDefault():

 

 阻止浏览器执行与事件相关的默认动作,与0级DOM中返回false一样

 

clientX, clientY:

 

 鼠标相对于浏览器的x坐标y坐标

 

screenX, screenY:

 

 鼠标相对于显示器左上角的x坐标y坐标

 

IE下的处理方式

 

IE下没有addEventListener,但是有自己类似的方法:attachEvent,这个方法只有两个参数,第一个参数为事件类型的前面需要加”on”,由于 ie下没有捕获,所以没有类似标准浏览器的第三个参数。

 

IE上可以对元素进行多次同样的绑定,标准浏览器只会绑定一次。ie下event对象不是事件处理程序传入的参数,而是全局的变量:window.event,例如中断冒泡用window.event.cancelBubble = true.

 

event常用属性

 

type:

 兼容DOM的type属性

 

srcElement:

 

 兼容DOM的target属性

 

clientX, clientY:

 

 兼容DOM的clientX, clientY属性

 

cancelBubble:

 

 布尔值,设为true同调用stopPropagation()

 

returnValue:

 

 布尔值,设为false同调用preventDefault()

 

卸载方法:

Object.removeEventListener(eventType,handler,useCapture);//DOM标准的事件卸载方式

Object.detachEvent(eventType,handler);//IE内核的事件卸载方式

  

  

4 事件传播过程的阻止

 

  浏览器在执行事件处理函数都会传递一个event对象,改event对象有个

  stopPropagation()方法可以阻止事件对象的传播(阻止捕获和冒泡).

 

  • 大小: 17 KB
分享到:
评论

相关推荐

    javascript事件详解

    JavaScript事件详解 JavaScript是一种基于浏览器的脚本语言,它的事件机制是实现动态交互的重要部分。在JavaScript中,事件是用户或浏览器对网页进行操作时触发的特定动作,比如点击按钮、鼠标移动等。本文将详细...

    JavaScript事件对象深入详解

    这篇深入详解将帮助我们理解如何在DOM(文档对象模型)以及不同浏览器环境下有效地使用事件对象。 在DOM中,事件对象通常作为参数传递给事件处理程序。例如,当用户点击一个按钮,`onclick`事件处理程序会接收到一...

    javascript 内存模型实例详解

    JavaScript的内存模型是理解其运行机制的关键部分,主要包括原始数据类型和引用数据类型的处理,以及内存的两个主要区域:调用栈和堆。下面将详细解释这些概念。 1. **JavaScript 原始数据类型的变量声明和赋值** ...

    javaScript中DOM模型使用详解+XMLHttpRequest异步请求使用

    JavaScript中的DOM(Document Object Model)模型是Web开发中不可或缺的一部分,它为HTML和XML文档提供了一个结构化的表示,并允许通过JavaScript来动态地访问和修改页面内容。DOM模型的诞生源于90年代末期的浏览器...

    [完全手册:JavaScript动态网页开发详解.教程.光盘的源文件

    在动态网页开发中,DOM(文档对象模型)是JavaScript操作HTML和CSS的重要接口。通过DOM,JavaScript可以找到、修改、添加或删除网页中的任何元素。教程会详细讲解如何使用JavaScript来操纵DOM,实现网页的动态更新。...

    【JavaScript源代码】javascript事件冒泡,事件捕获和事件委托详解.docx

    尽管在实际应用中事件捕获使用较少,但它有助于在事件到达目标元素之前进行预处理。 下面的代码展示了事件捕获的例子: ```javascript window.onload = function() { let box = document.getElementById("box...

    JavaScript对象模型

    ### JavaScript对象模型详解 #### 一、概述 在JavaScript中,对象模型是其核心特性之一,它决定了数据的存储方式以及程序的运行机制。本文旨在深入解析JavaScript对象模型的关键概念,包括基本数据类型、对象、...

    JavaScript 对象模型-执行模型

    ### JavaScript对象模型与执行模型详解 #### 一、引言 JavaScript作为一种强大的脚本语言,在Web开发领域占据了举足轻重的地位。其独特的对象模型和执行模型为开发者提供了灵活多变的功能,使得JavaScript能够轻松...

    【ASP.NET编程知识】ASP.NET的事件模型(很适合学习的文章).docx

    ASP.NET 事件模型详解 ASP.NET 事件模型是 ASP.NET 编程语言中一个非常重要的概念,它是 ASP.NET 应用程序的核心机制之一。事件模型是指在 ASP.NET 应用程序中,页面的事件处理机制,即页面的生命周期中各个阶段的...

    《JavaScript基础与案例开发详解》

    由于提供的文件信息不包含实质性的内容描述,而是反复提及《JavaScript基础与案例开发详解》这本书以及一个网址***,这导致无法从中抽取具体的知识点。为了满足您的要求,我将基于“JavaScript基础与案例开发”这一...

    js事件详解-0-1-2级模型.pdf

    标题提到的“js事件详解-0-1-2级模型”涉及到了JavaScript中事件的分层模型。JavaScript事件模型是前端开发中处理用户交互的核心机制之一,主要包括了事件捕获、目标阶段和事件冒泡三个阶段,这个模型被广泛地理解为...

    Javascript凌厉开发 Ext详解与实践 书本代码

    在《JavaScript凌厉开发 Ext详解与实践》中,作者可能详细讲解了以下几个方面: 1. JavaScript基础:包括变量、数据类型、控制结构、函数、对象等核心概念,以及原型链、闭包等高级特性。 2. DOM操作:讲解如何通过...

    JavaScript凌厉开发Ext详解与实践(源码)

    JavaScript凌厉开发Ext详解与实践是一本由清华大学出版社出版,张鑫、黄灯桥和杨彦强合著的专业书籍,其源码提供了丰富的实践案例,帮助读者深入理解并掌握JavaScript和ExtJS技术。这本书主要围绕JavaScript的Ext库...

    【JavaScript源代码】基于事件冒泡、事件捕获和事件委托详解.docx

    在JavaScript中,事件处理是网页交互的核心部分,而事件冒泡、事件捕获和事件委托则是JavaScript事件模型中的三个重要概念。理解这三个概念对于优化网页性能和编写高效代码至关重要。 事件冒泡是指事件从最深的节点...

    完全手册:JavaScript动态网页开发详解(1-8章pdf格式)

    这份"完全手册:JavaScript动态网页开发详解(1-8章)"提供了全面的知识点,帮助初学者和进阶者深入理解JavaScript的核心概念和技术。下面我们将逐章探讨这八章中的关键内容。 第一章:JavaScript入门 这一章主要...

    完全手册-JavaScript动态网页开发详解

    以下是对“JavaScript动态网页开发详解”这一主题的关键知识点进行的详尽解读。 ### 一、JavaScript基础 #### 1.1 JavaScript概述 - **定义**:JavaScript是一种轻量级的编程语言,用于实现客户端脚本,是...

    JavaScript的事件机制详解

    事件是将JavaScript脚本与网页联系在一起的主要方式,是JavaScript中最重要的主题之一,深入理解事件的工作机制以及它们对性能的影响至关重要。本文将详细探讨JavaScript的事件机制,并对比分析了浏览器之间的不同,...

    JavaScript详解.doc

    与Sun公司的Java不同,JavaScript并非一种面向对象的语言,而是基于对象的,它允许直接操作内置对象,如DOM(文档对象模型)。 JavaScript与HTML的结合主要有两种方式。第一种是在HTML文档中直接嵌入JavaScript代码...

    JavaScript网站特效详解

    首先,JavaScript的核心在于它的事件驱动模型。这意味着网页中的元素可以响应用户的交互,如点击、滚动或鼠标悬停,从而触发相应的函数执行。通过理解事件监听器和事件处理程序的工作原理,开发者可以创建出响应用户...

    javascript-document对象详解(下).zip

    在这个“javascript-document对象详解(下)”的压缩包中,我们可以通过三个文件来深入理解这个核心概念。 首先,`29.document-fun.html`可能是一个包含实际代码示例的HTML文件,它展示了`document`对象在实践中的...

Global site tag (gtag.js) - Google Analytics