JavaScript学习总结(九)事件详解
转自:http://segmentfault.com/a/1190000002174034
事件处理程序
在DOM中定义了一些事件, 而响应某个事件的函数就叫事件处理程序(或事件侦听器)。事件处理程序的名字一般以“on”开头,例如:onclick等
事件冒泡与捕获
事件流指的是页面中接收事件的顺序,IE,火狐和chrome浏览器都是事件冒泡,所谓是事件冒泡指的是事件最开始由最具体的元素接收,然后逐级向上传播到不具体的节点。而事件捕获则正好相反,事件捕获是由Netscape提出的,事件冒泡和捕获具体如下图所示:
虽然事件捕获是Netscape唯一支持的事件流模型,但目前IE9,火狐和谷歌也都支持这种事件流模型。
事件冒泡的好处
因为事件具有冒泡机制,因此我们可以利用冒泡的原理,把事件加到父级上,触发执行效果。这样做的好处当然就是提高性能了,
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload = function () {
var aUl = document.getElementsById("bubble");
var aLi = aUl.getElementsByTagName("li");
for(var i = 0;i<aLi.length;i++){
aLi[i].onmouseover = function () {
this.style.backgroundColor = "blue";
};
ali[i].onmouseout = function () {
this.style.backgroundColor = "";
}
}
};
</script>
</head>
<body>
<div>
<ul id = "bubble">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
</body>
这样我们就可以做到li上面添加鼠标事件。但是如果说我们可能有很多个li用for循环的话就比较影响性能。
下面我们可以用事件委托的方式来实现这样的效果。html不变:
<script type="text/javascript">
window.onload = function () {
var aUl = document.getElementsById("bubble");
var aLi = aUl.getElementsByTagName("li");
//不管在哪个事件中,只要你操作的那个元素就是事件源。
// ie:window.event.srcElement
// 标准下:event.target
aUl.onmouseover = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == "li"){
target.style.background = "blue";
}
};
aUl.onmouseout = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() = "li"){
target.style.background = "";
}
}
};
</script>
那么,如何阻止事件的冒泡呢,看下面一个例子:
<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//阻止事件冒泡后,你点击灰色盒子,整个过程只弹一次对话框了(注意与默认情况对比)
function showMsg(obj,e)
{
alert(obj.id);
stopBubble(e)
}
//阻止事件冒泡函数
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
</script>
点击黑色外围的效果图:
DOM 0级事件处理程序
通过js指定事件处理程序通常是将回调函数赋给这个事件处理程序的属性。每个元素都有自己的事件处理程序属性(属性小写,例如:onclick)
btn.onclick = function(){
console.log('hello');
};
使用DOM 0级指定的事件处理程序被认为是元素的方法。因此,this指向当前元素:
var btn = document.getElementById('myDiv');
//DOM上触发的事件会产生一个事件对象event
btn.onclick = function (event) {
alert(this.id);//myDiv
};
DOM level 1
DOM level 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。
DOM level 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。
第二版的工作草案在 2000 年 9 月 29 日。
值得一提的是:DOM level 0 并不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 IE 3.0 中的等价功能性的一种定义。
DOM 2级事件处理程序
DOM 2级定义了两个方法,用于指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),他们都接受三个参数:
1.事件名。比如上面的click
2.作为事件处理程序的函数。
3.布尔值(true表示捕获阶段调用事件处理程序,false表示冒泡阶段)
通过Element对象的addEventListener方法,也可以定义事件的回调函数。
//element.addEventListener(event, function, useCapture)
var btn = document.getElementById('myDiv');
btn.addEventListener('click', function () {
console.log(this.id);
},false);
IE中的事件处理程序
IE9之前的IE浏览器不支持addEventListener()和removeEventListener()。
与其他浏览器不同的是,IE使用的是attachEvent()和detachEvent()方法来为DOM添加事件处理程序,由于IE8及更早版本只支持事件冒泡,所以他们只接受两个参数:
1、事件处理程序名称(前面要加on)
2、事件处理程序函数
使用attachEvent()添加的事件处理程序如下:
var btn = document.getElementById('myDiv');
btn.attachEvent('onclick', function () {
console.log(this.id);
});
值得注意的是,使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,所以,此时this等于window
事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。event对象会被作为第一个参数传递给事件监听的回调函数。我们可以通过这个event对象来获取到大量当前事件相关的信息:
type (String) — 事件的名称
target (node) — 事件起源的DOM节点
currentTarget?(node) — 当前回调函数被触发的DOM节点(后面会做比较详细的介绍)
bubbles (boolean) — 指明这个事件是否是一个冒泡事件(接下来会做解释)
preventDefault(function) — 这个方法将阻止浏览器中用户代理对当前事件的相关默认行为被触发。比如阻止<a>元素的click事件加载一个新的页面
cancelable (boolean) — 这个变量指明这个事件的默认行为是否可以通过调用event.preventDefault来阻止。
stopPropagation (function) — 取消事件的进一步捕获或冒泡,bubbles为true使用这个方法
eventPhase:返回一个数字,表示事件目前所处的阶段,0为事件开始从DOM表层向目标元素传播,1为捕获阶段,2为事件到达目标元素,3为冒泡阶段。
此外,事件对象还可能拥有很多其他的属性,但是他们都是针对特定的event的。比如,鼠标事件包含clientX和clientY属性来表明鼠标在当前视窗的位置。
另外,stopPropagation()方法用于立即停止事件在DOM中的传播,即取消进一步的事件冒泡或捕获。
var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
alert("clicked");
event.stopPropagation();
};
//避免触发在document.body上的事件处理程序
document.body.onclick = function (event) {
alert("Body clicked");
};
只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完毕,event对象就会自动销毁。
IE中的事件对象
在DOM 0级中添加事件处理程序时,event对象是作为window对象的一个属性存在的:
var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
var event = window.event;
alert(event.type);//click
};
IE 的event对象同样也包含与创建它的事件相关的属性和方法。
cancleBubble 布尔 默认值时false,但可以被设置成true来取消事件冒泡,与dom中的 stopPropagation()方法相同。
returnValue 布尔 默认值是true,当设置成false时用以取消事件的默认行为 与dom中的preventDefault()相同。
srcElement 元素 事件的目标,与dom中的target属性相同。
type 字符串 被触发的事件类型。
click事件
当用户点击以后,event对象会包含以下属性。
pageX,pageY:点击位置相对于html元素的坐标,单位为像素。
clientX,clientY:点击位置相对于视口(viewport)的坐标,单位为像素。
screenX,screenY:点击位置相对于设备显示屏幕的坐标,单位为设备硬件的像素
clientX,clientY
图示:clientX和clientY,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标(不包含滚动条区域)
偏移量
通过以下4个属性可以取得元素的偏移量。
(1)offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。
(2)offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。
(3)offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。
(4)offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。
pageX,pageY
这两个属性表示鼠标光标在页面中的位置,在页面没有滚动的情况下,pageX,pageY的值与clientX,clientY的值相等
滚动大小
滚动大小,指的是包含滚动内容的元素的大小。
以下是4个与滚动大小相关的属性。
(1)scrollHeight:在没有滚动条的情况下,元素内容的总高度。
(2)scrollWidth:在没有滚动条的情况下,元素内容的总宽度。
(3)scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。
(4)scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。
焦点事件
焦点事件会在页面元素获得或失去焦点时触发,有以下4个焦点事件:
1. blur:元素失去焦点时触发,该事件不冒泡
2. focus:元素获得焦点时触发。不冒泡
3. focusin:元素获得焦点时触发,冒泡
4. focusout:元素失去焦点时触发,冒泡
鼠标事件
DOM 3级定义了9个鼠标事件:
click:当用户点击鼠标主键通常是指鼠标左键或按回车键时触发。
dbclick:用户双击鼠标时触发
mousedown:当用户按下鼠标任意一个键都会触发,这个事件是不能够通过键盘触发的。
mousemove:当鼠标在某元素周围移动时重复触发,该事件不能通过键盘事件触发。
mouseout:当鼠标离开元素时触发,这个事件不能通过键盘触发。
mouseover:当鼠标进入元素时触发,这个事件不能够通过键盘触发。
mouseenter:类似“mouseover”,但不冒泡,而且当光标移到后代元素上不会触发。
mouseleave:类似“mouseout”,但不冒泡。在元素上方是不触发。
mouseup:当用户释放鼠标按键时触发,不能够通过键盘触发。
传递给鼠标事件处理程序的事件对象有clientX和clientY属性,它们指定了鼠标指针相对于包含窗口的坐标。加入窗口的滚动偏移量,就可以把鼠标位置转换成文档坐标。
页面上的所有元素都支持鼠标事件。除了mouseenter和mouseleave外,所有的事件都冒泡,并且他们的默认行为是可以被取消掉的。但取消鼠标事件的默认行为可能会影响到其他事件,因为有些鼠标事件是相互依赖的。
mouseenter和mouseover的不同:
http://www.w3school.com.cn/tiy/t.asp?f=jquery_event_mouseenter_mouseover
拖拉事件
(1)drag事件
drag事件在源对象被拖拉过程中触发。
(2)dragstart,dragend事件
dragstart事件在用户开始用鼠标拖拉某个对象时触发,dragend事件在结束拖拉时触发。
(3)dragenter,dragleave事件
dragenter事件在源对象拖拉进目标对象后,在目标对象上触发。dragleave事件在源对象离开目标对象后,在目标对象上触发。
(4)dragover事件
dragover事件在源对象拖拉过另一个对象上方时,在后者上触发。
(5)drop事件
当源对象被拖拉到目标对象上方,用户松开鼠标时,在目标对象上触发drop事件。
JavaScript学习总结(九)事件详解的更多相关文章
- Javascript学习之三元运算符详解
本文主要是通过实例为大家介绍javascript三元运算符相关内容,希望对初学者学习这部分内容有所帮助. 实例 <!DOCTYPE html> <html> <head& ...
- Javascript学习之Math对象详解
1.定义 Math 是一个内置对象, 为数学常量和数学函数提供了属性和方法. Math 不是一个函数对象 Math 不是一个构造器. Math 的所有属性和方法都是静态的 2.属性 Math.E ...
- Javascript学习之Function对象详解
JavaScript中的Function对象,就是我们常说的函数对象.在JS中,所有的函数也是以对象的形式存在的. 语法 充当Function对象的构造函数使用,用于结合new关键字构造一个新的Fun ...
- Javascript学习之Date对象详解
1.定义 创建 Date 实例用来处理日期和时间.Date 对象基于1970年1月1日世界协调时起的毫秒数 2.语法 构造函数 new Date() new Date(value) value代表自世 ...
- JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】
正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...
- JavaScript事件详解-zepto的事件实现
zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...
- JavaScript事件详解-jQuery的事件实现(三)
正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...
- JAVASCRIPT事件详解-------原生事件基础....
javaScirpt事件详解-原生事件基础(一) 事件 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能 ...
- JavaScript中的鼠标滚轮事件详解
JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...
- 第三天:JS事件详解-事件流
学习来源: F:\新建文件夹 (2)\HTML5开发\HTML5开发\04.JavaScript基础\6.JavaScript事件详解 学习内容: 1)基础概念 2)举例说明: 代码如上,如果用事件 ...
随机推荐
- Java反射--getDeclaredField()和getField()
Field getField(String name) 返回当前类以及所继承的类的所有public修饰的成员变量 Field getDeclaredField(String name) 返 ...
- vim 马哥
VIM编辑器 编辑模式 默认 输入模式 i 末行模式 : vim +# file #打开文件后直接跳到第#行 vim + file 直接跳到尾行 vim +/关键字 跳转到 ...
- java设计模式--六大原则
一.单一职责原则 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因.通俗来说,就是互相不相关的属性和方法不要放在一个类中,就好比之前简单工厂模式中介绍的那样,客户端(Customer)应该与工 ...
- 题解 P2016 【战略游戏】
题目 解法跟 dalao @real_ljs 类似,但没有用到递归 [分析] 题目相当于需要求覆盖这颗树需要的最小点数 用 \(Dp_{i,0/1}\) 表示在这棵树中,以 \(i\) 为根节点的子树 ...
- 微信支付第三方sdk使用
1.引入依赖:(对于依赖冲突自行解决) <dependency> <groupId>com.github.binarywang</groupId> <arti ...
- 2.redis-help使用,基本命令
redis 帮助 > help redis-cli Type: "help @<group>" to get a list of commands in < ...
- python全局灰度线性变换——自由设定图像灰度范围
全局线性变换的公式是s = (r-a)*(d-c)/(b-a)+c,其中a.b是原图片的灰度最小值和最大值,c.d是变换后的灰度值的最小值和最大值.r是当前像素点的灰度值,s是当前像素点变换后的灰度值 ...
- CF 1095C Powers Of Two
题目连接:http://codeforces.com/problemset/problem/1095/C 题目: C. Powers Of Two time limit per test 4 seco ...
- 数学之美_正态分布(Python代码)
1 在概率统计中,我们针对某个事件当中各个样本发生的概率的频率进行统计,用一个函数的形式写出的这个概率的频率函数就叫做分布函数. 2 分布函数顾名思义,就是某个连续事件发生频率的汇总表示.再直白一点儿 ...
- 获取IP和IP地址
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>; <script type= ...