所谓事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间

一、事件流

在页面上,单击某个元素的同时,也单击了它的包含容器。事件流就是描述的从页面中接收事件的顺序。IE是事件冒泡流,Netscape是事件捕获流。
事件冒泡:事件开始时,由最具体的元素接收,然后逐级向上传播到较为不具体的节点;(所有现代浏览器都支持事件冒泡)
事件捕获:不太具体的节点最早接收到事件,最具体的节点最后接收到事件。(老版本浏览器不支持)

DOM事件流

DOM2级事件规定的事件流包括三个阶段:1、事件不惑阶段;2、处于目标阶段;3、事件冒泡阶段

DOM事件流中,实际的目标在捕获阶段不会接收到时间

二、事件处理程序

事件就是用户或浏览器自身执行的某种动作,如click/load/mousedown,这些都是事件的名字。
事件处理程序:是响应某个事件的函数

为事件指定事件处理函数的方法有3种:

1、HTML事件处理程序

某个元素支持的每种事件,都可以在元素内部,使用与事件处理程序同名的HTML属性来指定。这个属性的值是能够执行的JavaScript代码,既可以包含要执行的具体动作,也可以调用在页面其他地方定义的脚本。

<input type="button" value="点我有惊喜" onclick="alert('hello,vicky!')" />

缺点:
1、存在时差,用户可能会在HTML元素加载完就触发相应事件,而这时相应的事件处理程序还没有加载完,就会报错
2、使得HTML代码和JavaScript代码耦合,所以不推荐使用!

2、DOM0级事件处理程序

每个元素都有自己的事件处理程序属性,这些属性通常全部小写,将这种属性的值设置为一个函数,就可以指定事件处理程序。

var btn = document.getElementById("btn");//取得一个要操作对象的引用
btn.onclick = function () {alert("hello vicky!");
}

3、DOM2级事件处理程序

DOM2级事件定义了两个方法:addEventListener( ) removeEventListener( ),都接受三个参数,要处理的事件名,事件处理函数,一个布尔值(true表示在捕获阶段调用事件处理程序,false表示在冒泡阶段)

var btn = document.getElementById("btn");
btn.addEventListener("click", function (){alert("hello vicky!");
},false);
btn.addEventListener("click",function () {alert("hello jay!")
}, false);//可以添加多个事件处理程序,且按照其添加的顺序触发

通过addEventListener()添加的事件处理程序只能通过 removeEventListener()来移出。事件处理程序是在其依附的元素的作用域中运行

4、IE事件处理程序

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。事件处理程序在全局作用域中运行,添加的事件处理程序都会被添加到冒泡阶段

var btn = document.getElementById("btn");
btn.attachEvent("onclick",function(){alert("hello vicky!");
});
btn.attachEvent("onclick",function () {alert("hello jay!");
});//添加多个事件处理程序,以添加顺序的相反顺序执行

5、跨浏览器的事件处理程序

var EventUtil = {//添加事件处理程序addHandler: function (element,type,handler) {if (element.addEventListener) {element.addEventListener(type,handler,false);//DOM2级} else if (element.attachEvent) {element.attachEvent("on" + tye,handler);//IE的方法} else {element["on" + tyle] = handler;//DOM0级}},//取消事件处理程序removeHandler: function (element,type,handler) {if (element.removeEventListener) {element.removeEventListener(type,handler,false);} else if (element.detachEvent) {element.detachEvent("on" + tye,handler);} else {element["on" + tyle] = null;}}
}

三、事件对象

在出发DOM上的某个事件时,会产生要给事件对象event

1、DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入到事件处理程序中。event对象包含于创建它的特定事件有关的属性和方法。

//属性
bubbles:Boolean //表明事件是否冒泡
cancelable:Boolean //表明是否可以取消事件的默认行为
currentTarget:Element //事件处理程序当前正在处理事件的那个元素
defaultPrevented:Boolean //是否调用了preventDefault()
detail:Integer //细节信息
eventPhase: Integer //1,捕获阶段;2,处于目标阶段;3,冒泡阶段
target:Element //事件的目标
trusted:Boolean //是否为浏览器生成
type:Sting //被触发事件的类型//方法
preventDefault()  //取消事件的默认行为
stopImmediatePropagation() //取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation() //取消事件的进一步捕获或冒泡。

在事件处理程序内部,对象this始终等于currentTarget的值,target则只包含事件的实际目标

2、IE中的事件对象

不同之处:
1、event对象作为window对象的一个属性存在
2、事件的目标 window.event.srcElement
3、returnValue=false相当于preventDefault()

3、跨浏览器的事件对象

var EventUtil = {//获取事件对象getEvent: function (event) {return event ? event : window.event;},//获取事件目标对象getTarget: function (event) {return event.target || event.srcElement;},//阻止默认行为preventDefault: function (event) {if (event.preventDefault) {event.preventDefault();} else {event.returnValue = false;//取消默认行为}},//停止事件冒泡stopPropagation: function (event) {if (event.stopPropagation) {event.stopPropagation();} else {event.cancleBubble = true;}}
}

四、事件类型

1、UI事件

UI事件:指的是那些不一定与用户操作有关的事件。主要有:
load事件:页面完全加载后再window上面触发
unload事件:页面完全卸载后在window上触发
abort事件:用户停止下载过程时,如果嵌入的内容还没加载完在object元素上面触发
error事件:发生错误时触发
select事件:用户选择文本框时触发
resize事件:窗口或框架的大小变化时触发
scroll事件:用户滚动带滚动条的元素中的内容时触发

(1)load事件

当页面完全加载后,就会触发window上面的load事件

1)可以为图像设置load事件。

注意:在创建新的img元素时,要在指定其src属性之前先指定事件。新图像元素不一定要从添加到文档后才开始下载,只要设置了src属性就会开始下载。

2)为script元素指定事件处理程序

注意:与图像不同,只有在设置了script元素的src属性并将该元素添加到文档后,才会开始下载JavaScript文件,即指定src属性和指定事件处理程序的先后顺序不重要。

(2)unload事件

在文档被完全卸载后触发,只要用户从一个页面切换到另一个页面,就会发生unload事件。

(3)resize事件

当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件
注意:不要在这个事件的处理程序中加入计算量大的代码,因为这些代码很有可能会被频繁执行,从而导致浏览器反应明显变慢。当然,这个缺点也是有办法来解决的,那就是函数节流 ,详情请见之前博客【JavaScript】函数节流

2、焦点事件

blur:在元素失去焦点时触发
focus:在元素获得焦点时触发
这两个事件都不冒泡,所有浏览器都支持它们

3、鼠标与滚轮事件

(1)鼠标事件

click:单击主鼠标或者按下回车键触发
dbclick:双击主鼠标时触发
mousedown:用户按下了任意鼠标按钮时触发
mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发。此事件不冒泡,且光标移动到后代元素上不触发
mouseleave:位于元素上的光标移动到元素范围之外时触发
mouseover:鼠标指针在元素内部移动时触发
mouseout:鼠标指针由一个元素移到另一个元素上时触发
mouseup:释放鼠标按钮时触发

//鼠标事件触发顺序
(1)mousedown
(2)mouseup
(3)click
(4)mousedown
(5)mouseup
(6)dbclick

1)位置属性:

clientX,clientY:到浏览器视口区的左边和上边的值
screenX,screenY:到显示屏幕左边和上边的值
offsetX,offsetY:到元素左边和上边的值
2)修改键
shiftKey,ctrlKey,altKey,metaKey.

//打印出用户按下的修改键var text = document.getElementById("text");EventUtil.addHandler(text,"keydown",function (event) {var event = EventUtil.getEvent(event);var keys = new Array();if (event.shiftKey) {keys.push("shift")}if (event.ctrlKey) {keys.push("ctrl");}console.log(keys);}) ;

3)相关元素
发生mouseover和mouseout事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标指针从一个元素的编辑之内移动到另一个元素的边界之内

//获取相关元素getRelatedTarget: function (event) {if (event.relatedTarget) {//DOMreturn event.relatedTarget;} else if (event.toElement) {//mouseout时IE的toElement保存相关元素return event.toElement;} else if (event.fromElement) {//mouseover时IE的fromElement保存相关元素return event.fromElement;} else {return null;}}

4)鼠标按钮
event对象存在一个button属性,其值有3种:0表示主鼠标按钮,1表示中间的鼠标按钮,2表示次鼠标按钮

(2)鼠标滚轮事件

将mousewheel事件处理程序指定给页面中的任何元素或document对象,即可处理鼠标滚轮交互操作
使用鼠标事件应注意的问题:
(1)使用click事件执行代码
(2)不要使用onmouseover向用户显示新的选项。原因是 屏幕阅读器中,无法触发mousedown和mouseover事件
(3)不要使用dbclick执行重要的操作。因为键盘无法触发这个事件

4、键盘事件

keydown:用户按下键盘上的任意键时触发
keypress:用户按下键盘上的字符键时触发
keyup:用户释放键盘上的键时触发
textInput:在文本插入文本框之前触发

(1)键码

在发生keydown和keyup事件时,event对象的keyCode属性中会包含一个代码,与键盘上一个特定的键对应。

(2)字符编码

发生keypress事件意味着按下的键会影响到屏幕中文本的显示。
charCode属性:只有在发生keypress事件时才包含值,而且值是ASCII编码。要想跨浏览器取得字符编码,必须首先检测charCode属性是否可用,如果不可用则使用keyCode

//获取charCodegetCharCode: function (event) {if (typeof event.charCode == "number") {return event.charCode;} else {return event.keyCode;}}

(3)textInput事件

用户在可编辑区域中输入字符时,就会触发这个事件
textInput事件的event对象中包含一个data属性,这个属性的值就是用户输入的字符(不是编码)。

var textbox = document.getElementById("textbox");
EventUtil.addHandler(textbox,"textInput",function (event) {event = EventUtil.getEvent(event);alert(event.data);
})

5、HTML5事件

(1)contexmenu事件

contextmenu事件表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而提供自定义的菜单

//contextmenu事件EventUtil.addHandler(window,"load",function (event) {var div = document.getElementById("myDiv");EventUtil.addHandler(div, "contextmenu", function (event) {event = EventUtil.getEvent(event);EventUtil.preventDefault(event);var menu = div.nextElementSibling;menu.style.left = event.clientX + "px";menu.style.right = event.clientY + "px";menu.style.visibility = "visible";});EventUtil.addHandler(document, "click", function (event) {document.getElementById("myMenu").style.visibility = "hidden";})});


右键出现自定义的上下文信息

(2)readystatechange事件

readystatechange事件的目的是提供与文档或元素的加载状态有关的信息
可能的状态有5种:

uninitialized(未初始化):对象存在但尚未初始化
loading(正在加载):对象正在加载数据
loaded(加载完毕):对象加载数据完成
interactive(交互):可以操作对象了,但还没有完全加载
complete(完成):对象已经加载完毕

并非所有对象都会经历readyState的这几个阶段
栗子:

//readystatechange事件,确定外部js是否加载完毕EventUtil.addHandler(window, "load", function () {var script = document.createElement("script");EventUtil.addHandler(script, "readystatechange", function (event) {var event = EventUtil.getEvent(event);var target = event.getTarget(event);if (target.readyState == "loaded" || target.readyState == "complete") {EventUtil.removeHandler(target, "readystatechange", arguments.callee);alert("event.js is loaded");}});script.src = "test.js";document.body.appendChild(script);});//readystatechange 事件,确定外部css是否加载完毕EventUtil.addHandler(window, "load", function () {var link = document.createElement("link");link.type = "text/css";link.rel = "stylesheet";EventUtil.addHandler(link,"readystatechange", function (event) {var event = EventUtil.getEvent(event);var target = EventUtil.getTarget(event);if (target.readyState == "loaded" || target.readyState == "complete") {EventUtil.removeHandler(target, "readystatechange", arguments.callee);}});link.href = "test.css";document.getElementsByTagName("head")[0].appendChild(link);});//以上两个函数,最重要的是一并检测readyState的两个状态,并在调用了一次事件处理程序后就将其移除

五、事件委托

1、事件委托

对”事件处理程序过多“这个问题的解决方案就是事件委托,事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如,click事件会冒泡到document对象上,所以可以为整个页面指定一个onclick事件处理程序,而不必给每个可单击的元素分别添加。

事件委托的优点:
(1)在页面中设置时间处理程序所需的时间更少。只添加一个事件处理程序所需的DOM引用更少,花费时间少
(2)整个页面占用的内存空间更少,能够提升整体性能。

适合使用时间委托技术的事件有:click/mousedown/mouseup/keydown/keyup/keypress

2、移出事件处理程序

内存中留有那些过时不用的“空事件处理程序”,也是造成Web应用程序内存与性能问题的主要原因,解决问题的一种方法就是移除这些事件处理程序。

btn.onclick = null;

在页面卸载之前,使用onunload事件,移除所有事件处理程序

六、巩固学习的新知识

String.fromCharCode( ): 可接受一个指定的Unicode值,返回对应的字符串

/\d/.test(String.fromCharCode(EventUtil.getCharCode(event)))//判断按键按下的是否为数字

hasArrtibute( ):如果存在指定属性,则hasAttribute方法返回true,否则返回false。
specified属性:HTML DOM属性,查明是否已规定某属性

PS.《JavaScript高级程序设计》书又刷了一遍,还是又学习了很多新的知识,我觉着写博客是一种巩固学习的好方法,看书看一遍,把书上的代码敲一遍,再在博客中梳理一遍,整个知识框架就会很清晰。最近心里也有点着急,看书速度有些慢了,又买了好几本新书,不知道内推之前还来不来的及看完了。英雄不打无准备之仗,所以,加油!

【JavaScript】事件相关推荐

  1. javascript事件列表解说

    javascript事件列表解说 事件 浏览器支持 解说 一般事件 onclick IE3.N2 鼠标点击时触发此事件 ondblclick IE4.N4 鼠标双击时触发此事件 onmousedown ...

  2. javascript --- 事件托付

    javascript 之 事件托付 长处:1.提高性能(仅仅须要对父级进行操作,子节点相同会拥有其相关属性和方法) 2.对于新加入的事件.也让其拥有父级事件的属性 <!doctype html& ...

  3. 【探讨】javascript事件机制底层实现原理

    前言 又到了扯淡时间了,我最近在思考javascript事件机制底层的实现,但是暂时没有勇气去看chrome源码,所以今天我来猜测一把 我们今天来猜一猜,探讨探讨,javascript底层事件机制是如 ...

  4. javaScript事件(二)事件处理程序

    一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 前面提到,事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字.响应 ...

  5. onpaste事件不生效_从实际开发中来看JavaScript事件循环的使用场景

    前言: 本文是介绍结合DOM事件流和JavaScript事件循环解决一个工作中的实际问题的过程,很多东西不只是面试的时候才会用得到 文中涉及到的代码demo地址:drag-and-eventloop ...

  6. javascript 事件对象

    btn.onclick = function (event) {// event 就是事件对象var e = event || window.event; // window.event是兼容低版本I ...

  7. JavaScript事件详解-jQuery的事件实现(三)

    正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...

  8. JavaScript 事件入门知识

    JavaScript事件是由访问Web页面的用户引起的一系列操作; 例如:用户点击;当用户执行某些操作的时候,再去执行一系列代码; 一 事件介绍 事件一般是用于浏览器和用户操作进行交互;最早是IE和N ...

  9. JavaScript事件绑定

    本文介绍一些JavaScript事件绑定的常用方法及其优缺点,同时在最后展示一个由 Dean Edwards 写的一个比较完美的事件绑定方案. 传统方式 element.onclick = funct ...

  10. 我理解的javascript事件循环(一)

    javascript事件循环分为2种:一种是浏览器端事件循环,一种是node端事件循环. 此文只是捋一捋我对浏览器端事件循环的理解. 前言 我们都知道 JavaScript 是一门单线程语言,这意味着 ...

最新文章

  1. C# DateTimePicker控件如何精确设置显示时分秒
  2. 第一章 面向对象编程
  3. Spring AOP 切点(pointcut)表达式
  4. day18 面向对象
  5. linux apache jk,Linux下Apache+Tomcat+JK实现负载均衡和群集的完整过程
  6. 数字滤波器(二)--最小相位延时系统和全通系统
  7. “苹果税”收的太过分!苹果被连罚9周,总金额超3亿
  8. 去中心化抵押借贷市场当前总借款量94.24亿美元
  9. 家庭记账本开发进度6
  10. ibatis的ibatorForEclipse的安装与配置和ibator的错误日志查看
  11. LINUX下载编译iLBC
  12. 《通信原理》樊昌信、《移动通信》——知识点总结
  13. h5 兑换商品 页面模版_H5商城静态页面(模板)
  14. VB2010新特性之——标识语言版本的新命令行选项/langversion (Visual Basic)
  15. win7使用命令提示符怎么运行C语言,Win7如何打开命令行窗口?Win7打开命令提示符的多种方法...
  16. 万用表蜂鸣器档の响一声
  17. 树莓派4B Ubuntu 21.04 自动温控开关风扇以及RPi.GPIO避坑指南
  18. Verilog数字系统设计——8位数字比较器
  19. Ajax.NET中的ajax.js脚本
  20. Linux操作系统安装

热门文章

  1. linux gpio 模拟串口,STM32的GPIO口模拟串口通信.rar
  2. Firewalld概述
  3. android 语音识别 之 讯飞语音移植
  4. 2021年高处安装、维护、拆除最新解析及高处安装、维护、拆除考试技巧
  5. 前端小知识点:IP地址的FQDN查询
  6. 服务器装系统崩溃,服务器系统崩溃不要慌,因为我用了这招!
  7. 学系统集成项目管理工程师(中项)系列19b_成本管理(下)
  8. 分治法——最近对问题
  9. 2021最新汇总数据结构与算法面试题(准备面试的可以看看)
  10. blockly 代码html,Blockly 代码生成