JavaScript中的事件处理程序
JavaScript和HTML之间的交互是通过事件实现的。事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间。可以使用事件处理程序来预订事件,以便在事件发生的时候执行响应的代码。这种观察者模式的模型,使得JavaScript代码与HTML和CSS代码之间形成了松散耦合。
事件流
事件流描述的是从页面中接受事件的顺序。但是值得注意的是,在当年的浏览器大战中的主角们采用的是几乎完全相反的事件流概念。IE的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流。
事件冒泡
IE的事件流叫做事件冒泡(event bubbing),即事件右最具体的元素接受,然后逐级向上传播到不具体的元素,以下面的代码为例:
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title>
</head>
<body><div id="btn">点我</div>
</body>
</html>
如果你单击了#btn,那么在IE的页面中,这个事件会如下传播:
div->body->html->document
可以看到,事件首先在div上发生,div就是我们单击的元素。然后事件沿着DOM树向上传播,一直到document对象。
所有的现代浏览器都支持事件冒泡。IE9,Firefox,Chrome和Safari则将事件一直冒泡到window对象。
事件捕获
事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该是最后接收到事件。事件捕获的顾名思义就是在事件到达预定的目标之间捕获它。以上面的代码作为例子,那么单击div的时候会按照与冒泡相反的顺序触发事件。
div->body->html->document
在这个过程中,document对象先接收到click事件,然后事件沿着DOM树依次向下,一直传递到目标元素。
IE9,Firefox,Chrome和Safari都支持事件捕获。“DOM2级事件”规范要求事件应该从document对象开始传播,但实际上这些浏览器都是从window对象开始捕获事件。
DOM事件流
DOM事件流比事件毛婆和事件捕获稍微复杂一点点。它规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。
以前面的代码为例。单击div
事件处理程序
HTML事件处理程序
<input type="button" value="Click" id="go" onclick="showMessage()" />
这玩意儿就是传说中的HTML事件处理程序。最明显的缺点就是:HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就要同时修改HTML和JavaScript代码。
DOM0级事件处理程序
通过JavaScript制定事件处理程序的传统方法,就是讲一个函数赋值给一个叫做“事件处理程序”的属性。每个元素都有自己的事件处理程序属性,这些属性通常全部都是小写,例如onclick。将事件处理程序设置为一个函数,就可以指定事件处理程序。
var btn=document.getElementById("myBtn");
btn.onclick=function(){alert("Clicked!");
}
要使用JavaScript指定事件处理程序,必须先获得对象元素的引用,然后为其指定事件处理程序的函数。
事件处理程序是在元素的作用域中运行的,也就是说程序中的this指向的是当前元素。
var btn=document.getElementById("myBtn");
btn.onclick=function(){alert(this.id);//"myBtn"
}
以这种当时添加的事件处理程序会在事件流的冒泡阶段被处理。
通过将事件处理程序属性的值设置成null就可以删除事件处理程序。
btn.onclick=null;
DOM2级事件处理程序
“DOM2级事件”规定了两个方法用于操作事件处理程序:addEventListener()和removeEventListener()。所有的节点都包含这两个方法,接收三个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后的参数如果是true,表示在事件捕获阶段调用事件处理程序,如果是false,表示在事件冒泡阶段调用事件处理程序。
var btn=document.getElementById("myBtn");
btn.addEventListener("click",function(){alert(this.id);
},false);
DOM0级事件处理程序只能为一个元素添加唯一的某一个事件的处理程序。如果为一个元素添加了两个click的处理程序,后定义的程序会覆盖掉之前定义的程序,其实也就是给变量a多次赋值一样。使用DOM2级事件处理程序的好处之一就是:可以添加多个添加多个事件处理程序。
var btn=document.getElementById("myBtn");
btn.addEventListener("click",function(){alert(this.id);
},false);
btn.addEventListener("click",function(){alert("hello,world");
},false);
这两个事件处理程序会按照添加的顺序触发。
通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除。通过addEventListener()添加的匿名函数无法移除,因为移除是传入的参数一添加处理程序时使用的参数必须相同。
为了最大限度地兼容浏览器,建议在大多数情况下豆浆事件处理程序添加到事件流的冒泡阶段。
IE中的事件处理程序
IE中有类似于DOM的两个方法:attachEvent()和detachEvent()。这两个方法接受两个参数:事件处理程序名称和事件处理程序函数。attachEvent()添加的事件处理程序都会添加到冒泡阶段
var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(){alert("alert");
});
要注意哟,第一个参数是“onclick”而不是“click”。前面说到,在DOM0级事件中,事件处理程序的作用域是元素的作用域,而在使用attachEvent()时,作用域变成了全局作用域,此时this等于window
var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(){alert(this==widnow);//"true"
});
与addEventListener()一样,attachEvent()也可以用来为一个元素天剑多个事件处理程序,不过与DOM方法不同的是,事件处理程序不是按照添加的顺序执行,而是以相反的顺序执行。
可以使用detachEvent()移除使用attachEvent()添加的事件处理程序。与DOM方法一样必须提供相同的参数,添加的匿名函数不能被移除。
因此跨浏览器的事件处理程序可以这么写:
(来自《JavaScript高级程序设计》)
var EventUtil = {addHandler: function (element, type, handler) {if (element.addEventListener) {element.addEventListener(type, handler, false);} else if (element.attachEvent) {element.attachEvent("on" + type, handler);} else {element["on" + type] = handler;}},removeHandler: function (element, type, handler) {if (element.removeEventListener) {element.removeEventListener(type, handler, false);} else if (element.detachEvent) {element.detachEvent("on" + type, handler);} else {element["on" + type] = null;}}
};
var btn = document.getElementById("myBtn");
var handler = function () {alert("Clicked");};
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);
参考:《JavaScript高级程序设计》
转载于:https://www.cnblogs.com/zhanglun/p/3634570.html
JavaScript中的事件处理程序相关推荐
- 这就是为什么我们需要在React的类组件中绑定事件处理程序
by Saurabh Misra 索拉·米斯拉(Saurabh Misra) 这就是为什么我们需要在React的类组件中绑定事件处理程序 (This is why we need to bind ev ...
- 理解JavaScript中的事件
在很多语言的学习中,"事件"都是一个比较难理解,但是又是一个很重要的概念.JavaScript中的事件处理也是一样,正因为有了事件处理,才会出现Ajax拖动的效果.本文就讨论一下J ...
- react中绑定点击事件_在React中绑定事件处理程序的最佳方法
react中绑定点击事件 by Charlee Li 通过李李 在React中绑定事件处理程序的最佳方法 (The best way to bind event handlers in React) ...
- 【前端学习】前端学习第十五天:JavaScript中的事件模型
在各种浏览器中存在三种事件模型:原始事件模型.DOM事件模型和IE事件模型: 一.原始事件模型: 原始事件模型被所有浏览器支持: 在原始事件模型中.事件一旦发生就直接调用事件处理函数,事件不会向别的对 ...
- 12.在JavaScript中的事件模型如何理解?
一.事件与事件流 javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件.鼠标事件.自定义事件等 由于DOM是一个树结构,如果在 ...
- javascript中的事件问题的总结
一.什么是事件? 事件就是DOM和浏览器之间的交互行为(只要触发了这个行为,也就相当于触发了事件),我们可以通过事件监听来绑定事件,例如:box.οnclick=function(){},如果我们点击 ...
- 浅谈JavaScript中的事件
事件在javascript中是响应用户的一种基本操作,本文列举了两种javascript中的事件模型及其绑定的方式,希望能对你的学习带来一点帮助.这些都是非常基础的但或许其中有你所遗漏.(以下事件均针 ...
- JavaScript学习笔记06【高级——JavaScript中的事件】
w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...
- java基础66 JavaScript中的事件、localtion对象、screen对象(网页知识)
1.JavaScript中的事件注册 1.1.事件的注册方式 方式1:直接在html元素上注册<body onLoad="ready()"></body > ...
最新文章
- 寒羽对帝国的理解(通向高手之路)(转)
- Alpha 冲刺报告(6/10)
- MTK 驱动开发(15)---I2C
- java socket plc 通信_三菱两个FX5U 通信和程序
- SpringBoot 利用过滤器Filter修改请求url地址
- 小甲鱼python学习笔记1
- 计算机网络技术毕业生实习报告_20XX计算机网络技术毕业生实习报告1000字
- 转载:LTE中的各种ID含义
- 二维数组指针的理解和应用
- C-COT 【目标跟踪】个人理解
- python输入用户名和密码_验证Python中的用户名和密码输入
- 解决安装PyMySQL一直停在Building wheels for collected package:cryptography, cffi, pycparser的问题...
- 一文搞懂 Web Worker(原理到实践)
- i am freshman
- crm客户关系管理系统总结
- 牛牛手中有三根木棍,长度分别是a,b,c。牛牛可以把任一一根木棍长度削短,牛牛的目标是让这三根木棍构成一个三角形,并且牛牛还希望这个三角形的周长越大越好。
- 2013.06.25nbsp;雅思教父刘洪波7…
- RHCA412-ansible
- 1.Spring Boot 前言
- android修改字体粗细
热门文章
- 个人博客迁移到托管平台Netlify
- python sched_Python用sched执行周期性任务
- git创建分支及从分支下载代码
- c语言程序设计何钦铭视频教程,C语言程序设计 (何钦铭 颜晖 著) 高等教育出版社第1章 教案.ppt...
- oracle dg 删除归档,简单DG归档日志删除脚本
- DataGear 制作支持全国、省、市三级数据钻取效果的地图数据可视化看板
- 体育类游戏,3D 足球射门 ,Cocos Creator 3D 实现,附源码!
- php 循环分批量获取数据库数据
- 深度解析布谷鸟过滤器(上篇)
- mysql查询相关语法总结