JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
本篇体验JavaScript事件的基本面,包括:
■ 事件必须在页面元素加载之后起效
■ 点击事件的一个简单例子
■ 为元素注册多个点击事件
■ 获取事件参数
■ 跨浏览器事件处理
□ 事件必须在页面元素加载之后起效
有这样一段简单的代码:
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title></title><style>#box {background: blue;height: 100px;width: 100px;left: 50px;top: 50px;}</style></head><body><div id="box"></div></body>
现在,我们想给id为box的div添加事件,创建一个script.js文件。
(function() {var ele = document.getElementById("box");ele.onclick = function() {this.style.background = "red";};}());
是一个匿名函数,只要被引用,自动运行。
如果把script.js放在head区域。
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title></title>......<script src="script.js"></script></head>
点击页面蓝色区域会报错:Cannot set property 'onclick' of null
找不到需要实施onclick事件的元素。如果我们把script.js放在body区域底部,又会怎样呢?
<body><div id="box"></div><script src="script.js"></script></body>
点击页面蓝色区域背景色变成红色。
由此可以看出:事件必须在页面元素加载完毕之后才可以实施。
以上,通过把JavaScript代码放在需要实施事件元素的下方,保证了先加载元素,再执行事件,这很好。而实际上,通过window的onload方法也可以保证所有页面元素加载完毕再执行事件。
修改script.js的代码为:
(function () {window.onload = function() {var ele = document.getElementById("box");ele.onclick = function () {this.style.background = "red";};};}());
把script.js代码放在head部分。点击页面蓝色区域背景色变成红色。
□ 点击事件的一个简单例子
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title></title><style>.on {background-color: white;color: black;}.off {background-color: black;color: white;}</style><script src="script.js"></script></head><body class="on"><h1>Hello World</h1><p>欢度国庆</p><button id="open">开</button><button id="close">关</button></body>
script.js的代码为:
(function () {window.onload = function() {var openBtn = document.getElementById("open");var closeBtn = document.getElementById("close");openBtn.onclick = function() {document.body.className = "on";};closeBtn.onclick = function() {document.body.className = "off";};};
一切运行正常。但,如果我们在script.js中给开按钮再注册一个事件。
(function () {window.onload = function() {var openBtn = document.getElementById("open");var closeBtn = document.getElementById("close");openBtn.onclick = function() {document.body.className = "on";};closeBtn.onclick = function() {document.body.className = "off";};openBtn.onclick = function() {alert('hello');};};}());

当点击"开"按钮后,弹出alert。由此可以看出:每次只能为元素注册一个onclick事件。
□ 为元素注册多个点击事件
使用addEventListener方法,可以为元素同时注册多个点击事件。
修改script.js代码如下:
(function () {window.onload = function() {var openBtn = document.getElementById("open");var closeBtn = document.getElementById("close");var open = function() {document.body.className = "on";};var close = function() {document.body.className = "off";};//第三个参数设置成false,表示允许事件冒泡openBtn.addEventListener("click", open, false);openBtn.addEventListener("click", function() { alert('hello'); }, false);closeBtn.addEventListener("click", close, false);};}());
当然,也可以移除注册的事件。
//移除EventListner事件openBtn.removeEventListener("click", open, false);
注意:在IE8下没有addEventListner,应该使用attachEvent。
openBtn.attachEvent("onclick", function(evt)){alert(evt.srcElement);//相当于target属性document.body.className = "on";};
○ attachEvent只有2个参数
○ 事件名称是onclick,而不是click
○ event.srcElement相当于event.target
如果在IE8下注销事件。
openBtn.detachEvent("onclick",函数名称);
□ 获取事件参数
在每次发生事件的时候,所有的事件参数信息都被放在了一个event变量中。修改script.js代码为:
(function () {window.onload = function() {var openBtn = document.getElementById("open");var closeBtn = document.getElementById("close");var open = function (e) {alert(e.type + " " + e.target);document.body.className = "on";};var close = function (e) {alert(e.type + " " + e.target);document.body.className = "off";};//第三个参数设置成false,表示允许事件冒泡openBtn.addEventListener("click", open, false);closeBtn.addEventListener("click", close, false);};}());
可见,函数的事件参数在大多数情况下被省略了,如果想获取事件信息,这个event参数还是很有用的。
□ 跨浏览器事件处理
正因为,在不同的浏览器下事件处理方式不同,比如在chrome下接收addEventListener方法,而在IE8下接收attachEven方法,我们有必要针对跨浏览器提供一个通用的事件处理机制。
创建eventUtiltiy.js文件。
var eventUtility = {addEvent: function(ele, type, fn) {if (typeof addEventListener !== "undefined") {ele.addEventListener(type, fn, false);} else if (typeof attachEvent !== "undefined") { //比如在IE8下ele.attachEvent("on" + type, fn);} else {//获取属性通过obj.属性名称,等同于obj[属性名称]//执行事件通过obj.事件名称,等同于obj[事件名称]ele["on" + type] = fn;}},removeEvent: function(ele, type, fn) {if (typeof removeEventListener !== "undefined") {ele.removeEventListener(type, fn, false);} else if (typeof detachEvent !== "undefined") {ele.detachEvent("on" + type, fn);} else {ele["on" + type] = null;}},getTarget: function(event) {if (typeof event.target !== "undefined") {return event.target;} else {return event.srcElement;}},preventDefault: function(event) {if (typeof event.preventDefault !== "undefined") {event.preventDefault();} else {event.returnValue = false;}},getCharCode: function(event) {if (typeof event.charCode === "number") {return event.charCode;} else {return event.keyCode;}}};
页面部分。
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title></title><style>.on {background-color: white;color: black;}.off {background-color: black;color: white;}</style></head><body class="on"><h1>Hello World</h1><p>欢度国庆</p><button id="open">开</button><button id="close">关</button><script src="eventUtility.js"></script><script src="script.js"></script></body>
script.js部分。
(function () {var openBtn = document.getElementById("open");var closeBtn = document.getElementById("close");var open = function () {//alert(e.type + " " + e.target);document.body.className = "on";};var close = function () {//alert(e.type + " " + e.target);document.body.className = "off";};eventUtility.addEvent(openBtn, "click", open);eventUtility.addEvent(closeBtn, "click", close);}());
“JavaScript进阶系列”包括:
JavaScript进阶系列01,函数的声明,函数参数,函数闭包
JavaScript进阶系列02,函数作为参数以及在数组中的应用
JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
JavaScript进阶系列06,事件委托
JavaScript进阶系列07,鼠标事件
JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数的更多相关文章
- JavaScript进阶系列07,鼠标事件
鼠标事件有Keydown, Keyup, Keypress,但Keypress与Keydown和Keyup不同,如果按ctrl, shift, caps lock......等修饰键,不会触发Keyp ...
- JavaScript进阶系列06,事件委托
在"JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数"中已经有了一个跨浏览器的事件处理机制.现在需要使用这个 ...
- JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
本篇主要体验函数参数个数不确定情况下的一个解决方案.先来看一段使用函数作为参数进行计算的实例. var calculate = function(x, y, fn) { return fn(x, y) ...
- JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
本篇体验通过硬编码.工厂模式.构造函数来创建JavaScript对象. □ 通过硬编码创建JavaScript对象 当需要创建一个JavaScript对象时,我们可能这样写: var person = ...
- JavaScript进阶系列02,函数作为参数以及在数组中的应用
有时候,把函数作为参数可以让代码更简洁. var calculator = { calculate: function(x, y, fn) { return fn(x, y); } }; var su ...
- JavaScript进阶系列01,函数的声明,函数参数,函数闭包
本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...
- 前端入门20-JavaScript进阶之异步回调的执行时机
声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...
- javascript进阶系列专题:闭包(Closure)
在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中. var fun = function(){ console.log("平底斜"); } f ...
- javascript进阶系列专题:作用域与作用域链
字面意思,作用域是指变量和函数的作用范围,换言之,作用域决定了变量和函数的可见性和有效时间.javascript作用域是用函数来区分,与其他语言的大括号不同. for (var i=0; i<5 ...
随机推荐
- Eclipse的git插件冲突合并方法
Eclipse有一个git的插件叫EGit,用于实现本地代码和远程代码对比.合并以及提交.但是在本地代码和远程代码有冲突的时候,EGit的处理方案还是有点复杂.今天就彻底把这些步骤给理清楚,并公开让一 ...
- generator自动生成代码
idea设置generator自动生成代码: http://blog.csdn.net/sunny243788557/article/details/45166397
- java实现xml格式与javabean之间的转换XmlUtil类
XmlUtil类:不多说,直接撸代码: /** * java 转换成xml * @Title: toXml * @Description: TODO * @param obj 对象实例 * @retu ...
- 【转载】Java与C++语言在作用域上的差异浅析
http://developer.51cto.com/art/200906/126199.htm 差异一:变量作用域的不同 如下面这段程序代码是符合C++语言的语法要求的.其可以在C语言下正常运行.但 ...
- 【LOJ】#2526. 「HAOI2018」苹果树
题解 这计数题多水啊我怎么调了那么久啊 我不想老年化啊QAQ (注意这里的二叉树带标号) 考虑\(g[i]\)表示\(i\)个点二叉树所有节点的深度和,\(f[i]\)表示\(i\)个点的二叉树两两节 ...
- 【LOJ】#2117. 「HNOI2015」实验比较
题解 把所有=的点连起来,一个图合法肯定它是一个有向树森林 我们新建一个点,把这个点和其他所有树的树根连起来 定义\(dp[u][j]\)表示第u个点长度为j的序列的方案数 转移方法是 \(dp[u] ...
- js跨越请求的2中实现 JSONP /后端接口设置运行跨越header
由于浏览器同源策略,a域名的js向b域名ajax请求会被禁止.JS实现跨越访问接口有2中办法. 1.后端接口设置允许跨越的header头. //header('Access-Control-Allow ...
- 010 使用jquery实现小需求练习-------对应选择器的练习
1.需求 点击所有的 p 节点, 能够弹出其对应的文本内容 使第一个 table 隔行变色 点击 button, 弹出 checkbox 被选中的个数 2.程序 <!DOCTYPE html&g ...
- MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介
网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上. 我们知道MySQL的性能优化方法,一般有建立索引.规避复杂联合查询.设置冗余字段.建立中间表.查询 ...
- Mysql - 参数修改
概述 mysql的参数可以分为两类:a. 动态参数,数据库启动期间能被修改,而修改又分为两种(global级,session级).b. 静态参数,即数据库启动期间不能修改. 接下来利用参数wait_t ...