浅谈JavaScript之事件(上)
一 简述JavaScript及其在浏览器中的地位
(一) 浏览器主要构成
虽然不同浏览器之间存在差异(如Google Chrome,Firefox,Safari和IE等),但单从浏览器构成来说,大同小异,大致可归结为如下几类:
1.User Interface(用户界面):所谓用户界面,就是通过浏览器渲染出来,让用户可见的界面,如地址栏,书签菜单栏等;
2.Browser Engine(浏览器引擎):主要操作呈现的引擎界面;
3.Rendering Engine(渲染引擎):负责渲染响应请求内容,如负责解析HTML和CSS;
4.Networking(网络):负责网络呼叫处理,如http请求;
5.JS Interpreter(JavaScript 解释器):负责解析和执行javascript代码;
6.UI Back(UI后端):用于绘制组合框和窗口等基本组建;
7.Data Persistence(数据持久):通常用来持久化存储少量数据,如cookie等;
(二)JavaScript在浏览器中的地位
如上图,javascript处于浏览器中的核心位置,负责解释和执行js脚本,内置于浏览器中,通过浏览器提供的API来访问。
(三)JavaScript构成
关于javascript的构成,大致可归结为三个部分:ECMAScript,DOM和BOM。
1.ECMAScript是对js的约束和规范,如基本语法结构;
2.DOM就是文档对象模型,是交互的资源,如html文档;
3.BOM主要是对浏览器本身描述,如浏览器名称,版本号等;
(四)JavaScript基本执行原理
这里不深入谈及javascript的深层次执行原理,只是大致描述一下,关于更深层次的,在后续文章推出,与大家分享。
JS的执行原理,用一句话来归结之:单线程异步。下图很好地表述该过程。
所有的执行函数统一放在队列中进行排队。
二 事件流
所谓事件流,也可理解为事件的轨迹。一般地,将事件流分为三个阶段:捕获阶段,目标阶段和冒泡阶段。
下图为三个阶段的大致流程图。
(一)捕获阶段
捕获阶段处于事件流的第一阶段,该阶段的主要作用是捕获截取事件。在DOM中,该阶段始于Document,结束于body(当然,在现在的很
多高版本浏览器中,该过程结束于目标元素,只不过不执行目标元素而已,这也体现了目标元素具有双重范围)。
(二)目标阶段
目标阶段处于事件流的第二阶段,该阶段的主要作用是执行绑定事件。一般地,该阶段具有双重范围,即捕获阶段的结束,冒泡阶段的开始;
(三)冒泡阶段
冒泡阶段处于事件流的第三阶段,该阶段的主要作用是将目标元素绑定事件执行的结果返回给浏览器,处理不同浏览器之间的差异,主要在该阶段完成。
(四)三阶段在Dom中的完整流程
三 事件处理程序
js事件处理程序按照种类来划分,大致可分为五大类:HTML事件处理程序,DOM0级事件处理程序,DOM2级事件处理程序,IE事件处理程序和跨浏览器事件处理程序。
尤其是DOM0,DOM2和IE事件处理程序,利用它们之间的差异化有效地解决浏览器差异问题,从而实现跨浏览器的兼容性问题。
(一)html事件处理程序
所谓html事件处理程序,就是在dom结构中嵌套js代码。在html中,元素支持的所有事件,都可以使用与相应事件处理程序同名的html特性来指定,这个特性的值应该是能执行的js代码。
如点击事件。
<body>
<!--html事件处理程序-->
<input type="button" value="请点击" onclick="alert('测试html事件处理程序!!')"/>
</body>
当然,一般不采用如上方法,常规的做法是,将js代码定义在目标元素外部。因此,与如上相同功能的定义为:
目标元素
<body>
<!--html事件处理程序-->
<input type="button" value="请点击" onclick="HtmlEventHandlerProc()"/>
</body>
外部js
<script>
function HtmlEventHandlerProc() {
alert('测试html事件处理程序!!');
}
</script>
Tip:
1.事件处理程序中的代码,能够访问全局作用域中的任何变量;
2.每个function()存在一个局部变量,即事件对象event,通过event变量,可以直接访问事件对象。
<body>
<input type="button" value="请点击" onclick="alert(event.type)"/>
</body>
执行结果
3.在函数内部,this值等于事件的目标元素。
<body>
<input type="button" value="请点击" onclick="alert(this.value)"/>
</body>
执行结果
this具有扩展作用域的功能,其功能相当于
function myfunction() {
with (document) {
with (this) {
//add your logic
}
}
}
如果当前元素是一个表单元素,则作用域还会包含访问表单元素(父元素)的入口。
function myfunction() {
with (document) {
with (this.form) {
with (this) {
//add your logic
}
}
}
}
这样做,有什么本质意义呢?当然是想让事件处理程序更快捷访问表单其他字段(无需引用表单元素就能访问)
<form>
<input type="text" name="userName" value="Alan_beijing" />
<input type="button" value="测试表单元素" onclick="alert(userName.value)" />
</form>
执行结果
4.html事件处理程序存在哪些缺点?
缺点一:时差问题
缺点二:扩展的作用域链在不同浏览器中会导致不同结果
缺点三:html代码与js代码高度耦合
(二)DOM0级事件处理程序
DOM0级事件很好地解决了html和js代码强耦合的问题。
1.为元素绑定事件
var btn = document.getElementById('myBtn');
btn.onclick = function () {
alert('Clicked');
}
2.为元素解除事件
btn.onclick = null;
(三)DOM2级事件处理程序
DOM2级事件定义了两个方法来为目标元素绑定事件处理程序(addEventListener())和解除事件处理程序(removeEventListener()),所有节点中都包含这两个方法,并且他们都接收三个参数:
要处理的事件名,事件处理程序和一个布尔值(true表示是在捕获阶段进行,false表示在冒泡阶段进行)
1.为事件添加click事件处理程序(冒泡阶段进行)
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
alert(this.id);
}, false);
执行结果:
2.添加多个事件处理程序
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
alert(this.id);
}, false);
btn.addEventListener("click", function myfunction() {
alert("添加的第二个事件处理程序");
}, false);
执行结果:
3 移除事件处理程序
通过addEventListener()添加的事件处理陈旭只能使用removeEventListener()来移除,移除时,传入的参数与添加的程序时使用的参数相同
(这意味着匿名函数不能通过removeEventListener()来删除)
匿名函数不能删除
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
alert(this.id);
}, false); //不能删除,因为是匿名函数
btn.removeEventListener("click", function () {
alert(this.id);
}, false);
非匿名函数能删除
var btn = document.getElementById("myBtn");
var handler = function () {
alert(this.id);
}; btn.addEventListener("click", handler, false);
//删除事件处理程序
btn.removeEventListener("click", handler, false);
(四)IE事件处理程序
IE提供了两个方法来绑定和卸载事件处理程序,attachEvent()和detachEvent(),这两个方法均接收两个参数,即事件处理程序名称和事件处理程
序函数,并且在冒泡阶段添加(IE8及更早版本只支持冒泡)
1.为目标按钮添加绑定事件
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () {
alert("IE事件处理程序!!");
});
2.为目标按钮添加绑定事件
多个执行绑定事件的结果是倒过来的。
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () {
alert("IE事件处理程序1!!");
}); btn.attachEvent("onclick", function () {
alert("IE事件处理程序2!!");
});
3.为目标元素移除事件处理程序
注意:匿名事件处理程序是不能够移除的
var btn = document.getElementById("myBtn");
var handler = function () {
alert("IE事件处理程序");
};
//绑定事件
btn.attach("onclick", handler);
//移除事件
btn.detachEvent("onclick", handler);
(五)跨浏览器事件处理程序
在跨浏览器中,无非就是三种选择:DOM0级选择(不常用,基本被废弃),DOM2级选择和IE选择(不常用,IE8及以下版本)。
//定义EventUtil
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("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("事件处理程序跨浏览器!!");
};
//绑定事件处理程序
EventUtil.addHandler(btn, "click", handler);
//移除事件处理程序
EventUtil.removeHandler(btn, "click", handler);
四 事件类型
内容相对比较简单,这里就暂且列举主要内容,若有需要,会在下篇文章论述。
五 事件对象及其事件委托
介于文章篇幅有限,暂且列举主要内容,代码部分将在下篇文章论述。
六 版权区
- 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
- 博主网址:http://www.cnblogs.com/wangjiming/。
- 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
- 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。
- 可以转载该博客,但必须著名博客来源。
浅谈JavaScript之事件(上)的更多相关文章
- 浅谈JavaScript的事件(事件处理程序)
事件就是用户或者浏览器自身执行的某种动作.诸如click.load和mouseover,都是事件的名字.而响应某个事件的函数就叫事件处理程序.事件处理程序的名字以"on"开头,比如 ...
- 浅谈JavaScript的事件(事件模拟)
事件经常由操作或者通过浏览器功能触发,通过JavaScript也可以触发元素的事件.通过JavaScript触发事件,也称为事件的模拟. DOM中事件模拟 可以document的createEvent ...
- 浅谈javascript中事件冒泡与事件捕获
事件冒泡:一个事件会顺着他的层级一直往上传,一直传到document上为止,即从盒模型上看是从内到外的过程. 例: <!DOCTYPE html><html lang="e ...
- 浅谈JavaScript的事件响应
原文出处: Christian Heilmann 译文出处:Chajn Science 每当猴子们问我JavaScript和DOM里啥东西最牛逼时,我都会一巴掌打回去:卧槽还用问么当然是事件响应了 ...
- 浅谈JavaScript的事件(事件类型)
Web浏览器能够发生的事件有很多种类型,不同的事件类型有不同的事件信息.DOM3级的事件类型主要包括:UI事件,用户与页面上的元素交互时触发:焦点事件,元素获得或失去焦点触发:鼠标事件,用户通过鼠标在 ...
- 浅谈JavaScript的事件(事件对象)
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有关的信息.包括导致事件的元素.事件的类型和事件的相关信息.例如鼠标操作的事件中,会包含鼠标的位置信息.而键盘触发的 ...
- 浅谈JavaScript的事件(事件委托)
事件处理程序为Web程序提供了系统交互,但是如果页面中的事件处理程序太多,则会影响页面的性能.每个函数都是对象,都会占用内存,内存中对象越多,性能越差.需要事先为DOM对象指定事件处理程序,导致访问D ...
- 浅谈JavaScript的事件(事件流)
事件流描述的是从页面中接收事件的顺序.IE的事件流失事件冒泡,而Netspace的事件流失事件捕获. 事件冒泡 IE的事件流叫事件冒泡,即事件开始时,由具体的元素(文档中嵌套层次最深的节点)接收,然 ...
- 浅谈javascript函数节流
浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...
随机推荐
- IDEA鼠标显示javadoc的设置
IDEA鼠标显示javadoc的设置 从Eclipse切换到IDEA中以后最不适用的就是鼠标放到方法上没有注释弹出来给我看,很难受,每次使用ctrl+Q来看总觉得不开心,找了一下设置,设置方法如下: ...
- python之路(八)-迭代器&生成器
迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优点是 ...
- Strusts2
Strusts2的原理很简单,首先,地址栏输入http://xxxx/xxxx/webapp/xx.action首先,请求会通过httpservlet发送给tomcat容器,tomcat发现这个请求是 ...
- JSP与Servlet的关系
之前的文章里有说过,其实Servlet比JSP出现的早,JSP的本质就是Servlet,但是一个是jsp页面,一个是java类,硬要说他们的本质是一样的,搁谁都有点难以置信.后面的结论会更加让你吃惊. ...
- $(document).on('click','.classname',function(){}); VS $('.classname').on('click',function(){});
jquery中用on来绑定事件,经常的写法有$(document).on('click','.classname',function(){});$('.classname').on('click',f ...
- OC内存管理、非ARC机制、MRR机制
在Xcode里面,默认为ARC(auto reference counting),也就是自动内存管理机制,在这里我们要了解的是内存管理,肯定是不能让系统帮我们管理内存,我们需要将ARC关闭,首先在左边 ...
- [ 10.4 ]CF每日一题系列—— 486C
Description: 给你一个指针,可以左右移动,指向的小写字母可以,改变,但都是有花费的a - b 和 a - z花费1,指针移动也要花费,一个单位花费1,问你把当前字符串变成回文串的最小化费是 ...
- cf Round#273 Div.2
题目链接,点击一下 Round#273 Div.2 ================== problem A Initial Bet ================== 很简单,打了两三场的cf第一 ...
- 你可以这么理解五种I/O模型
因为项目需要,接触和使用了Netty,Netty是高性能NIO通信框架,在业界拥有很好的口碑,但知其然不知其所以然. 所以本系列文章将从基础开始学起,深入细致的学习NIO.本文主要是介绍五种I/O模型 ...
- jvm的垃圾回收和内存
垃圾回收: 对象的创建是我们程序员主导的,但是却没有与之相对应的delete方法来删除我们用完的对象,释放这些我们已经不需要再使用的对象的内存空间,gc:垃圾回收机制:指的就是JVM自带的一种释放无用 ...