浏览器事件是所有web程序的核心。javascript与HTML之间的交互是通过事件实现的。通过这些事件我们定义将要发生的行为。事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信。

1.事件流

一件事情发生后,在DOM节点之间传播的阶段,在DOM2级事件中包括三个阶段:

  • 捕获阶段(capture phase)
  • 目标阶段(target phase)
  • 冒泡阶段(bubbling phase)

(1)事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。

示例

<div>click me</div>

如果你点击了上面的div元素,那么会以下面的顺序触发click事件。
document > html > body > div

(2)事件冒泡

事件冒泡与事件捕获相反,它由最具体的元素(一般是嵌套最深的那个节点)开始接收,然后到不具体的元素节点文档。

<div>click me</div>

如果你点击了上面的div元素,那么会以下面的顺序触发click事件。
div > body > html > document

完整事件流实例:(来源:事件模型)

<div>
<p>Click Me</p>
</div> 如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。 var phases = {
1: 'capture',
2: 'target',
3: 'bubble'
}; var div = document.querySelector('div');
var p = document.querySelector('p'); div.addEventListener('click', callback, true);
p.addEventListener('click', callback, true);
div.addEventListener('click', callback, false);
p.addEventListener('click', callback, false); function callback(event) {
var tag = event.currentTarget.tagName;
var phase = phases[event.eventPhase];
console.log("Tag: '" + tag + "'. EventPhase: '" + phase + "'");
} // 点击以后的结果
// Tag: 'DIV'. EventPhase: 'capture'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'DIV'. EventPhase: 'bubble' 上面代码表示,click事件被触发了四次:<p>节点的捕获阶段和冒泡阶段各1次,<div>节点的捕获阶段和冒泡阶段各1次。

2事件处理程序(事件监听程序)

事件处理程序是指事件发生时,程序要执行的函数。DOM提供三种方法,可以用来为事件绑定监听函数。

(1)HTML事件处理程序 (HTML标签的on-属性)

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML属性来指定。
<input type="button" value="clickMe" onclick="alert("Clicked!")">

(2)DOM0级事件处理程序 (Element节点的事件属性)

通过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。

注意:以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。

window.onload=function(){
alert("clicked!");
}

(3)DOM2级事件处理程序

DOM2级事件处理程序定义了两个方法用于处理指定和删除事件处理程序的操作:

addEventListener();和removeEventListener();

所有DOM节点中都包含这两个方法,并且他们都接受3个参数:

  • 要处理的事件名,
  • 事件处理程序函数,
  • 布尔值(如果为true,表示在捕获阶段调用事件处理程序;如果为false,表示在冒泡阶段调用事件处理程序。)
btn.addEventListener("click",function(){
alert(this.id);
},false);

三种方法对比总结:

  • 第一种:违反了HTML与JavaScript代码相分离的原则;

  • 第二种:同一个事件只能定义一个监听函数,也就是说,如果定义两次onclick属性,后一次定义会覆盖前一次。

  • 第三种(推荐):可以针对同一个事件,添加多个监听函数。

    能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发回监听函数。

    除了DOM节点,还可以部署在window、XMLHttpRequest等对象上面,等于统一了整个JavaScript的监听函数接口。

3.事件代理或者事件委托(Event Delegation)

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,而不是给每一个子元素绑定事件(太麻烦了,如果添加新的子元素,还得改代码)通过事件代理(delegation)方法,绑定容器就可以监听所有子元素了。

//处理列表

var ul = document.querySelector('ul');
ul.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
}); //处理表格 var myTable = document.getElementById('my-table');
myTable.onclick = function () {
// 处理浏览器兼容
e = e || window.event;
var targetNode = e.target || e.srcElement;
// 测试如果点击的是TR就触发
if (targetNode.nodeName.toLowerCase() === 'tr') {
alert('You clicked a table row!');
}
}

4.事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素event.target,事件的种类event.type,以及与特定事件相关的信息。

下面是事件对象的属性和方法

5.事件类型(常用的)

鼠标事件

 ‘mousedown’ – 鼠标设备按下一个元素的时候触发mousedown事件。
‘mouseup’ – 鼠标设备从按下的元素上弹起的时候触发mouseup事件。
‘click’ – 鼠标点击元素的时候触发click事件。
‘dblclick’ – 鼠标双击元素的时候触发dblclick事件。
‘mouseover’ – 鼠标移动到某元素上的时候触发mouseover事件。
‘mouseout’ – 鼠标从某元素离开的时候触发mouseout事件。
‘mousemove’ – 鼠标在某元素上移动但未离开的时候触发mousemove事件。

键盘事件

‘keypress’ – 按键按下的时候触发该事件。
‘keydown’ – 按键按下的时候触发该事件,并且在keypress事件之前。
‘keyup’ – 按键松开的时候触发该事件,在keydown和keypress事件之后。

表单事件

‘select’ – 文本字段(input, textarea等)的文本被选择的时候触发该事件。
‘change’ – 控件失去input焦点的时候触发该事件(或者值被改变的时候)。
‘submit’ – 表单提交的时候触发该事件。
‘reset’ – 表单重置的时候触发该事件。
‘focus’ – 元素获得焦点的时候触发该事件,通常来自鼠标设备或Tab导航。
‘blur’ – 元素失去焦点的时候触发该事件,通常来自鼠标设备或Tab导航。

其它事件

‘load’ – 页面加载完毕(包括内容、图片、frame、object)的时候触发该事件。
‘resize’ – 页面大小改变的时候触发该事件(例如浏览器缩放)。
‘scroll’ – 页面滚动的时候触发该事件。
‘unload’ – 从页面或frame删除所有内容的时候触发该事件(例如离开一个页面)。

6补充:跨浏览器的事件处理程序与对象

之所以会存在跨浏览器的处理程序与对象,主要是因为IE的特殊。

(1)IE中使用attachEvent()事件处理程序

(2)IE中使用window.event获得对象

为了兼容性,需要编写跨浏览器的事件处理程序与对象。详细见JavaScript高级程序设计讲解。

快速理解Event事件的更多相关文章

  1. 理解js事件循环(event loop)

    队列:先进先出 栈:后进先出 javascript的Event Loop 和 Node.js的Event Loop 区别: js(运行在浏览器),有主线程.异步任务队列的概念: node.js使用li ...

  2. 理解DOM事件流的三个阶段

    本文主要解决两个问题: 1.什么是事件流 2.DOM事件流的三个阶段 事件流之事件冒泡与事件捕获 在浏览器发展的过程中,开发团队遇到了一个问题.那就是页面中的哪一部分拥有特定的事件? 可以想象画在一张 ...

  3. 简单总结焦点事件、Event事件对象、冒泡事件

    每学习一些新的东西,要学会复习,总结和记录. 今天来简单总结一下学到的几个事件:焦点事件.Event事件对象.冒泡事件 其实这几个事件应该往深的说是挺难的,但今天主要是以一个小菜的角度去尝试理解一些基 ...

  4. JavaScript 运行机制详解:深入理解Event Loop

    Philip Roberts的演讲<Help, I'm stuck in an event-loop>,详细.完整.正确地描述JavaScript引擎的内部运行机制. 一.为什么JavaS ...

  5. Storm快速理解

    转自:http://blog.csdn.net/colorant/article/details/8256039 更多云计算相关项目快速理解文档  http://blog.csdn.net/color ...

  6. C# event 事件学习

    C# event 事件学习 运行环境:Window7 64bit,.NetFramework4.61,C# 6.0: 编者:乌龙哈里 2017-02-26 章节: 简单事件编写 模拟 WPF 控件传递 ...

  7. saltstack之salt event事件用法

    event是一个本地的ZeroMQ PUB Interface,event是一个开放的系统,用于发送信息通知salt或其他的操作系统.每个event都有一个标签.事件标签允许快速制定过滤事件.除了标签 ...

  8. JavaScript:理解worker事件api

    如果你不是很了解Event事件,建议先看我上一篇随文javascript:理解DOM事件.或者直接看下文worker api. hack 首先,我们需要实例一个Worker的对象,浏览器会根据新创建的 ...

  9. javascript:理解DOM事件

    首先,此文不讨论繁琐细节,但是考虑到读者的心灵感受,本着以积极向上的心态,在此还是会列举示例说明. ​标题为理解DOM事件,那么在此拿一个简单的点击事件为例,希望大家看到这个例子后能触类旁通. DOM ...

随机推荐

  1. nodejs的jsonrpc调用

    记录下使用nodejs发送jsonrpc请求: var express = require('express'); var router = express.Router(); var request ...

  2. python中的单例模式的应用

    1 使用__new__方法 class Singleton(object):    def __new__(cls, *args, **kw):        if not hasattr(cls, ...

  3. 静态代码块,构造代码块,main()

    静态代码块 随Class 加载而加载,为Class 作初始化: 在main() 之前加载: 只执行一次: 构造代码块 随对象的创建而加载,为对象作初始化 public class day04 { pu ...

  4. javaEE Design Patter(2)详解3个设计模式

    Factory (bean creating) Proxy(Agent)(Aop)书有~ Templete(springMVC Facelets)//此处及以上忽略 工厂模式(Factory) 工厂模 ...

  5. vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)

    vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于“=”.“d”.“y”,我在无意中发现了它们所具有的相同的一些用法,先举以下三个例子: =nG dnG ynG 其中,n为行号.注意 ...

  6. Html5的新特性总结

    新加语义化标签: HTML5其实是关于图像,位置,存储,速度的优化和改进 图像: 到目前为止,基本上想要直接在网页上进行绘图还是不能轻易完成的,即使是几何图形也不可以.在浏览器当中直接能跟图片的交互操 ...

  7. zookeeper安装及使用

    0. 下载并安装 1. 开机启动 cd  /etc/rc.d/init.d touch zookeeper vi zookeeper #!/bin/bash #chkconfig #descripti ...

  8. 洛谷P1600 天天爱跑步(差分 LCA 桶)

    题意 题目链接 Sol 一步一步的来考虑 \(25 \%\):直接\(O(nm)\)的暴力 链的情况:维护两个差分数组,分别表示从左向右和从右向左的贡献, \(S_i = 1\):统计每个点的子树内有 ...

  9. 准备Activiti开发环境

    1.添加jar包 在activiti-5.13 -> wars 目录下 解压 activiti-rest.war ,导入WEB-INF\lib下所有包添加到classpath中. 由于使用的是O ...

  10. RocketMQ读书笔记4——NameServer(MQ的协调者)

    [NameServer简述] 对于一个消息队列集群来说,系统由很多机器组成,每个机器的角色.IP地址都不相同,而且这些信息是变动的(如在某些情况下,会有新的Producer或Consumer加入). ...