JavaScript事件的一个重要方面是它们拥有一些相对一致的特点,可以给你的开发提供更多的强大功能。最方便和强大的就是事件对象,他们可以帮你处理鼠标事件和键盘敲击方面的情况,此外还可以修改一般事件的捕获/冒泡流的函数。

 

一.事件对象

事件处理函数的一个标准特性是,以某些方式访问的事件对象包含有关于当前事件的上下文信息。

事件处理三部分组成:对象.事件处理函数=函数。例如:单击文档任意处。

document.onclick = function () {

alert('Dkf');

};

PS:以上程序的名词解释:click表示一个事件类型,单击。onclick表示一个事件处理函数或绑定对象的属性(或者叫事件监听器、侦听器)。document表示一个绑定的对象,用于触发某个元素区域。function()匿名函数是被执行的函数,用于触发后执行。

除了用匿名函数的方法作为被执行的函数,也可以设置成独立的函数。

document.onclick = box; //直接赋值函数名即可,无须括号

function box() {

alert('Dkf');

}

this关键字和上下文

在面向对象那章我们了解到:在一个对象里,由于作用域的关系,this代表着离它最近对象。

var input = document.getElementsByTagName('input')[0];

input.onclick = function () {

alert(this.value); //HTMLInputElement,this表示input对象

};

从上面的拆分,我们并没有发现本章的重点:事件对象。那么事件对象是什么?它在哪里呢?当触发某个事件时,会产生一个事件对象,这个对象包含着所有与事件有关的信息。包括导致事件的元素、事件的类型、以及其它与特定事件相关的信息。

事件对象,我们一般称作为event对象,这个对象是浏览器通过函数把这个对象作为参数传递过来的。那么首先,我们就必须验证一下,在执行函数中没有传递参数,是否可以得到隐藏的参数。

function box() { //普通空参函数

alert(arguments.length); //0,没有得到任何传递的参数

}

input.onclick = function () { //事件绑定的执行函数

alert(arguments.length); //1,得到一个隐藏参数

};

通过上面两组函数中,我们发现,通过事件绑定的执行函数是可以得到一个隐藏参数的。说明,浏览器会自动分配一个参数,这个参数其实就是event对象。

input.onclick = function () {

alert(arguments[0]); //MouseEvent,鼠标事件对象

};

上面这种做法比较累,那么比较简单的做法是,直接通过接收参数来得到即可。

input.onclick = function (evt) { //接受event对象,名称不一定非要event

alert(evt); //MouseEvent,鼠标事件对象

};

直接接收event对象,是W3C的做法,IE不支持,IE自己定义了一个event对象,直接在window.event获取即可。

input.onclick = function (evt) {

var e = evt || window.event; //实现跨浏览器兼容获取event对象

alert(e);

};

 

二.鼠标事件

鼠标事件是Web上面最常用的一类事件,毕竟鼠标还是最主要的定位设备。那么通过事件对象可以获取到鼠标按钮信息和屏幕坐标获取等。

1.鼠标按钮

只有在主鼠标按钮被单击时(常规一般是鼠标左键)才会触发click事件,因此检测按钮的信息并不是必要的。但对于mousedown和mouseup事件来说,则在其event对象存在一个button属性,表示按下或释放按钮。

非IE(W3C)中的button属性

说明

0

表示主鼠标按钮(常规一般是鼠标左键)

1

表示中间的鼠标按钮(鼠标滚轮按钮)

2

表示次鼠标按钮(常规一般是鼠标右键)

IE中的button属性

说明

0

表示没有按下按钮

1

表示主鼠标按钮(常规一般是鼠标左键)

2

表示次鼠标按钮(常规一般是鼠标右键)

3

表示同时按下了主、次鼠标按钮

4

表示按下了中间的鼠标按钮

5

表示同时按下了主鼠标按钮和中间的鼠标按钮

6

表示同时按下了次鼠标按钮和中间的鼠标按钮

7

表示同时按下了三个鼠标按钮

PS:在绝大部分情况下,我们最多只使用主次中三个单击键,IE给出的其他组合键一般无法使用上。所以,我们只需要做上这三种兼容即可。

function getButton(evt) { //跨浏览器左中右键单击相应

var e = evt || window.event;

if (evt) { //Chrome浏览器支持W3C和IE

return e.button; //要注意判断顺序

} else if (window.event) {

switch(e.button) {

case 1 :

return 0;

case 4 :

return 1;

case 2 :

return 2;

}

}

}

document.onmouseup = function (evt) { //调用

if (getButton(evt) == 0) {

alert('按下了左键!');

} else if (getButton(evt) == 1) {

alert('按下了中键!');

} else if (getButton(evt) == 2) {

alert('按下了右键!' );

}

};

2.可视区及屏幕坐标

事件对象提供了两组来获取浏览器坐标的属性,一组是页面可视区左边,另一组是屏幕坐标。

坐标属性

属性

说明

clientX

可视区X坐标,距离左边框的位置

clientY

可视区Y坐标,距离上边框的位置

screenX

屏幕区X坐标,距离左屏幕的位置

screenY

屏幕区Y坐标,距离上屏幕的位置

document.onclick = function (evt) {

var e = evt || window.event;

alert(e.clientX + ',' + e.clientY);

alert(e.screenX + ',' + e.screenY);

};

3.修改键

有时,我们需要通过键盘上的某些键来配合鼠标来触发一些特殊的事件。这些键为:Shfit、Ctrl、Alt和Meat(Windows中就是Windows键,苹果机中是Cmd键),它们经常被用来修改鼠标事件和行为,所以叫修改键。

修改键属性

属性

说明

shiftKey

判断是否按下了Shfit键

ctrlKey

判断是否按下了ctrlKey键

altKey

判断是否按下了alt键

metaKey

判断是否按下了windows键,IE不支持

function getKey(evt) {

var e = evt || window.event;

var keys = [];

if (e.shiftKey) keys.push('shift'); //给数组添加元素

if (e.ctrlKey) keys.push('ctrl');

if (e.altKey) keys.push('alt');

return keys;

}

document.onclick = function (evt) {

alert(getKey(evt));

};

 

三.键盘事件

用户在使用键盘时会触发键盘事件。“DOM2级事件”最初规定了键盘事件,结果又删除了相应的内容。最终还是使用最初的键盘事件,不过IE9已经率先支持“DOM3”级键盘事件。

1.键码

在发生keydown和keyup事件时,event对象的keyCode属性中会包含一个代码,与键盘上一个特定的键对应。对数字字母字符集,keyCode属性的值与ASCII码中对应小写字母或数字的编码相同。字母中大小写不影响。

document.onkeydown = function (evt) {

alert(evt.keyCode); //按任意键,得到相应的keyCode

};

不同的浏览器在keydown和keyup事件中,会有一些特殊的情况:

在Firefox和Opera中,分号键时keyCode值为59,也就是ASCII中分号的编码;而IE和Safari返回186,即键盘中按键的键码。

PS:其他一些特殊情况由于浏览器版本太老和市场份额太低,这里不做补充。

2.字符编码

Firefox、Chrome和Safari的event对象都支持一个charCode属性,这个属性只有在发生keypress事件时才包含值,而且这个值是按下的那个键所代表字符的ASCII编码。此时的keyCode通常等于0或者也可能等于所按键的编码。IE和Opera则是在keyCode中保存字符的ASCII编码。

function getCharCode(evt) {

var e = evt || window.event;

if (typeof e.charCode == 'number') {

return e.charCode;

} else {

return e.keyCode;

}

}

PS:可以使用String.fromCharCode()将ASCII编码转换成实际的字符。

keyCode和charCode区别如下:比如当按下“a键(重视是小写的字母)时,

在Firefox中会获得

keydown: keyCode is 65  charCode is 0

keyup:   keyCode is 65 charCode is 0

keypress: keyCode is 0  charCode is 97

在IE中会获得

keydown: keyCode is 65  charCode is undefined

keyup:   keyCode is 65  charCode is undefined

keypress: keyCode is 97  charCode is undefined

而当按下shift键时,在Firefox中会获得

keydown:keyCode is 16  charCode is 0

keyup: keyCode is 16   charCode is 0

在IE中会获得

keydown:keyCode is 16  charCode is undefined

keyup: keyCode is 16  charCode is undefined

keypress:不会获得任何的charCode值,因为按shift并没输入任何的字符,并且也不会触发keypress事务

PS:在keydown事务里面,事务包含了keyCode – 用户按下的按键的物理编码。

在keypress里,keyCode包含了字符编码,即默示字符的ASCII码。如许的情势实用于所有的浏览器 – 除了火狐,它在keypress事务中的keyCode返回值为0。

四.W3C与IE

在标准的DOM事件中,event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。

W3C中event对象的属性和方法

属性/方法

类型

读/写

说明

bubbles

Boolean

只读

表明事件是否冒泡

cancelable

Boolean

只读

表明是否可以取消事件的默认行为

currentTarget

Element

只读

其事件处理程序当前正在处理事件的那个元素

detail

Integer

只读

与事件相关的细节信息

eventPhase

Integer

只读

调用事件处理程序的阶段:1表示捕获阶段,2表示“处理目标”,3表示冒泡阶段

preventDefault()

Function

只读

取消事件的默认行为。如果cancelabel是true,则可以使用这个方法

stopPropagation()

Function

只读

取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法

target

Element

只读

事件的目标

type

String

只读

被触发的事件的类型

view

AbstractView

只读

与事件关联的抽象视图。等同于发生事件的window对象

IE中event对象的属性

属性

类型

读/写

说明

cancelBubble

Boolean

读/写

默认值为false,但将其设置为true就可以取消事件冒泡

returnValue

Boolean

读/写

默认值为true,但将其设置为false就可以取消事件的默认行为

srcElement

Element

只读

事件的目标

type

String

只读

被触发的事件类型

在这里,我们只看所有浏览器都兼容的属性或方法。首先第一个我们了解一下W3C中的target和IE中的srcElement,都表示事件的目标。

function getTarget(evt) {

var e = evt || window.event;

return e.target || e.srcElement; //兼容得到事件目标DOM对象

}

document.onclick = function (evt) {

var target = getTarget(evt);

alert(target);

};

事件流

事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。

事件冒泡,是从里往外逐个触发。事件捕获,是从外往里逐个触发。那么现代的浏览器默认情况下都是冒泡模型,而捕获模式则是早期的Netscape默认情况。而现在的浏览器要使用DOM2级模型的事件绑定机制才能手动定义事件流模式。

document.onclick = function () {

alert('我是document');

};

document.documentElement.onclick = function () {

alert('我是html');

};

document.body.onclick = function () {

alert('我是body');

};

document.getElementById('box').onclick = function () {

alert('我是div');

};

document.getElementsByTagName('input')[0].onclick = function () {

alert('我是input');

};

在阻止冒泡的过程中,W3C和IE采用的不同的方法,那么我们必须做一下兼容。

function stopPro(evt) {

var e = evt || window.event;

window.event ? e.cancelBubble = true : e.stopPropagation();

}

JavaScript(第二十四天)【事件对象】的更多相关文章

  1. JavaScript(第二十五天)【事件绑定及深入】

    事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型),一种是现代事件绑定(DOM2级模型).现代事件绑定在传统绑定上提供了更强大更方便的功能.   一.传统事件绑定的问题 传统事件绑定有内联模型 ...

  2. javaSE第二十四天

    第二十四天    363 1:多线程(理解)    363 (1)JDK5以后的Lock锁    363 A:定义    363 B:方法:    364 C:具体应用(以售票程序为例)    364 ...

  3. Gradle 1.12用户指南翻译——第二十四章. Groovy 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  4. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

  5. NeHe OpenGL教程 第二十四课:扩展

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. Python第二十四天 binascii模块

    Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...

  7. SQL注入之Sqli-labs系列第二十四关(二阶注入)

    开始挑战第二十四关(Second Degree Injections) 0x1 前言 SQL注入一般分为两类:一阶SQL注入(普通SQL注入),二阶SQL注入 .二次注入不是注入两次的意思,请不要混淆 ...

  8. “全栈2019”Java多线程第二十四章:等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. “全栈2019”Java第二十四章:流程控制语句中决策语句switch下篇

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. oracle 常用知识积累

    一.  基本操作 1.  表操作 1.1 复制建表 create table test as select * from dept; --从已知表复制数据和结构 create table test a ...

  2. bzoj 4026 dC Loves Number Theory

    把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...

  3. 使用AOP的好处

    原始代码的写法 既然要通过代码来演示,那必须要有例子,这里我的例子为: 有一个接口Dao有insert.delete.update三个方法,在insert与update被调用的前后,打印调用前的毫秒数 ...

  4. 【视频编解码·学习笔记】10. 序列参数集(SPS)介绍

    一.SPS 相关概念: SPS即 "Sequence Paramater Set",又称作序列参数集. SPS中保存了一组编码视频序列(Coded video sequence)的 ...

  5. linux命令类型及执行顺序

    一 为什么要使用命令行   当初级Linux用户面对缺乏图形界面的Linux时很多人都会抱怨:为何要死守命令行?为什么不采用人机互交好.更简单的图形界面呢?事实上,图形界面在某些任务方面确实高效而且简 ...

  6. 【BZOJ1926】粟粟的书架(主席树,前缀和)

    [BZOJ1926]粟粟的书架(主席树,前缀和) 题面 Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co ...

  7. FFT/NTT 总结

    本总结主要用于帮助个人理解,讲得不足之处,还请各位看官谅解 FFT 补充知识 \(n\)次单位复根(\(w_n\)): 使得\(z^n=1\)的一类复数,这些复数一共有\(n\)个,它们都分布在复平面 ...

  8. Spring【AOP模块】就是这么简单

    前言 到目前为止,已经简单学习了Spring的Core模块.....于是我们就开启了Spring的AOP模块了...在讲解AOP模块之前,首先我们来讲解一下cglib代理.以及怎么手动实现AOP编程 ...

  9. 【Spring源码分析】AOP源码解析(下篇)

    AspectJAwareAdvisorAutoProxyCreator及为Bean生成代理时机分析 上篇文章说了,org.springframework.aop.aspectj.autoproxy.A ...

  10. 初识 .net core和vs code

    定义:什么是.net core? .net core是一个跨各个不同操作系统运行的平台.时至今日,windows上.net framework已经发展成熟,可以用来开发windows平台下的几乎所有应 ...