javaScirpt事件详解-原生事件基础(一)

 

事件

JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能响应相关的操作。图片引用:UI Events

事件流

主要是当时的IE团队提出的事件流逝是事件冒泡流,而Netscape提出的是事件捕获流, 可以使用DOM2级定义的addEventListener()方法来处理在冒泡或者捕获阶段调用事件处理程序。

事件冒泡

即事件开始时由最具体的元素(文档中嵌套最深的节点)接收,然后逐级向上传播到较为不具体的节点。

事件捕获

即最外层的元素更早接收到事件,而最具体的元素应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。

DOM事件流

而“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后一个阶段是冒泡阶段。

addEventListener函数接收三个参数,要处理的事件名、作为事件处理程序的函数和一个布尔值,最后的布尔值如果是true,表示在不回阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

事件捕获:

//html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="a">
<div class="b">
<button class="c">click</button>
</div>
</div>
</body>
</html> var $body = document.querySelector("body"),
$a = document.querySelector(".a"),
$b = document.querySelector(".b"),
$c = document.querySelector(".c"); $body.addEventListener("click",function(){
console.log(this);
},true);
$a.addEventListener("click",function(){
console.log(this);
},true);
$b.addEventListener("click",function(){
console.log(this);
},true);
$c.addEventListener("click",function(){
console.log(this);
},true);

单击button,则

事件冒泡:

$body.addEventListener("click",function(){
console.log(this);
},false);
$a.addEventListener("click",function(){
console.log(this);
},false);
$b.addEventListener("click",function(){
console.log(this);
},false);
$c.addEventListener("click",function(){
console.log(this);
},false);

单击button,则

上述代码在IE9和其他现代浏览器都支持(测试页)。IE8及更早版本不支持DOM事件流只有事件冒泡。所以我们有两个阶段可以在目标对象上操作事件,但为了兼容性考虑,一般用冒泡的情况比较多。

事件处理程序

事件是用户或浏览器自身执行的某种动作,而响应某个事件的函数就叫做事件处理程序(或事件侦听器)

HTML事件处理程序

即内联式处理函数,以"on"开头:

<button onclick="alert(this)"></button>

虽然方便,但有很大问题,首先,存在时差问题,因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件;另一个缺点是:这样扩展事件处理程序的作用域链在不同浏览器会导致不同结果;而最后的缺点则是HTML与JavaScript代码紧密耦合,如果要更换事件处理程序,就要改动两个地方。

DOM0级事件处理程序

通过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。 每个元素(包括window和docuemnt)都有自己的事件处理程序属性,这些属性通常全部小写:

var btn = document.getElementById('myBtn');
btn.onclick = function(){
alert("Clicked");
}

以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。

DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,在上面的事件捕获和冒泡有用到。使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。

IE事件处理程序

IE实现的方法是:attachEvent()和detachEvent()。这两个方法接收相同的两个参数:事件处理程序名称与事件处理程序函数。通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段:

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick",function(){
alert("Clicked");
})

这里的参数中表行为的是onclick而非DOM的addEventListener()方法中的click,在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域,在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window

var btn = document.getElementById("myBtn");
btn.attachEvent('onclick',function(){
alert(this === window);// true
});

事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,所有浏览器都支持event对象,但支持方式不同。

DOM中的事件对象

event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。不过,所有事件都有下表的成员属性。

属性/方法 类型 读/写 说明
bubbles boolean 只读 表明事件是否冒泡
cancelable boolean 只读 表明是否可以取消事件的默认行为
currentTarget element 只读 其事件处理程序当前正在处理事件的那个元素
defaultPrevented boolean 只读 为true表示已经调用了preventDefault()DOM3新增
datail integer 只读 与事件相关的细节信息
eventPhase integer 只读 调用事件处理程序的阶段:1表示捕获阶段,2表示处于目标 3表示冒泡阶段
preventDefault() function 只读 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
stopImmediatePropagation() function 只读 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级新增)
stopPropagation() function 只读 取消事件的进一步捕获或冒泡,如果bubbles为true,则可以使用这个方法
target element 只读 事件的目标
isTrusted boolean 只读 返回一个布尔值,表明当前事件是否是由用户行为触发,还是由一个脚本生成的
type string 只读 被触发的事件的类型
view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的window对象

更详细的文档可以看 这里

在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则this,currentTarget和target包含相同的值。

根据event所拥有的属性,就可以更加细致的操作事件。在w3c的这篇Events中,我们可以知道哪些事件可以冒泡. 首先是冒泡事件,如果只需要在具体节点触发,而不冒泡到包裹层中,则可以使用与冒泡行为相关的一系列属性,举例:

<div class="a">
<a href="http://www.cnblogs.com"></a>
</div>

在这个div中,如果div和a都有监听点击事件,那么在点击a标签的时候(默认事件流在已过捕获阶段),会先触发a的点击事件,然后是div的点击事件,最后是a标签的默认事件。如果不想冒泡,也就是说点击a时只触发a的点击事件,则可以使用stopPropagation()方法:

var $a = document.querySelector("a");
$a.addEventListener("click",function(event){
if(event.bubbles){
event.stopPropagation();
}
});

也可以在处理程序里直接删除节点,也能阻止冒泡。 当然,有时我们不希望跳转页面,而是执行自定义的脚本,那就可以使用preventDefault()方法:

var $a = document.querySelector("a");
$a.addEventListener("click",function(event){
if(event.bubbles){
event.preventDefault();
// do something
}
});

有时我们可能会接手他人的代码,在不了解具体代码的情况下,如果只是单个独立事件需要修改,则可以在运行老的js代码之前,使用stopPropagation()方法。

$a.addEventListener('click',function(event){
event.preventDefault();
event.stopImmediatePropagation();
// do something
}) $a.addEventListener("click",function(event){
alert("这是a标签");
});

当然,冒泡并不是说是一件坏事,因为场景很多变,在某些场景下,冒泡也是很有用的,比如说事件代理(delegation)。 有时我们需要对生成的节点附加操作,event总是需要先找到element,再进行注册,才可以进行事件监听,那么对于这些生成的节点来说,当然可以在生成之后再次对该节点重新注册事件。但如果是生成了同一个标记的节点呢? 那么我们不仅需要把之前注册的事件remove,还需要重新绑定之前的标记,否则会二次触发。这时候事件代理 就可以解决这一类问题。根据DOM事件流,我们可以知道,在节点冒泡时,可以一直往上冒泡,所以,我们完全可以把事件代理给点击节点的父节点来做,根据event.target属性,我们可以知道指向触发事件的对象到底是谁,也因此,不用再使用繁琐的重新注册事件,就可以直接操作子元素。像jQuery,Zepto中都有关于事件代理的处理方法,后篇会继续涉及到。

$div.addEventListener("click",function(event){
alert("这是外层");
if(event.target) {
event.target.style.visibility = 'hidden';
}
});

冒泡也会有副作用,mouseout事件会导致离开内部节点时提前触发,为此,jQuery自定义了mouseenter和mouseleave事件,Zepto也有相应的事件。 只有在事件处理程序执行期间,event对象才会存在;一旦事件处理程序执行完成,event对象就会被销毁(闭包)

IE中的事件对象

在IE中访问event,特别是IE6~8尤其注意,在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。

var btn = document.getElementById('a');
btn.onclick = function(){
var event = window.event;
alert(event.type); //"click"
}

而IE中的event对象都会包含下表的属性和方法:

属性/方法 类型 读/写 说明
cancelBubble Boolean 读/写 默认值为false,但将其设置为true就可以取消事件冒泡(与DOM中的stopPropagation()方法的作用相同)
returnValue Boolean 读/写 默认值为false,但将其设置为false就可以取消事件的默认行为(与DOM中的preventDefault()方法的作用相同)
srcElement Element 只读 事件的目标(与DOM中的target属性相同)
type String 只读 被触发的事件的类型

事件类型

不表

事件模拟

结合jQuery和Zepto源码总结。

部分用例:event

长路漫漫,与君共勉

如果您看完本篇文章感觉不错,请点击一下右下角的推荐来支持一下博主,谢谢!
 
分类: javaScript
标签: javascript
---------------------->此文转载!

JAVASCRIPT事件详解-------原生事件基础....的更多相关文章

  1. javaScirpt事件详解-原生事件基础(一)

    事件 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能响应相关的操作.图片引用:UI Events 事件流 ...

  2. Android事件详解——拖放事件DragEvent

    1.Android拖放框架的作用? 利用Android的拖放框架,可以让用户用拖放手势把一个View中的数据移到当前layout内的另一个View中去. 2.拖放框架的内容? 1)拖放事件类 2)拖放 ...

  3. JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】

    正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...

  4. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

  5. DOM——事件详解

    事件 事件:触发-响应机制 事件三要素 事件源:触发(被)事件的元素 事件名称: click 点击事件 事件处理程序:事件触发后要执行的代码(函数形式) 事件的基本使用  var box = docu ...

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

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

  7. JavaScript中的鼠标滚轮事件详解

    JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...

  8. react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)

    第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...

  9. 第三天:JS事件详解-事件流

    学习来源: F:\新建文件夹 (2)\HTML5开发\HTML5开发\04.JavaScript基础\6.JavaScript事件详解 学习内容:  1)基础概念 2)举例说明: 代码如上,如果用事件 ...

随机推荐

  1. PullToRefresh 下拉刷新的样式修改

    资源文件结构图, 先看看下拉刷新头的布局, <?xml version="1.0" encoding="utf-8"?> <merge xml ...

  2. 减少GC开销的措施

    程序的运行会直接影响系统环境的变化,从而影响GC的触发.若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响.为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销.具体 ...

  3. oracle 树状查询

    做树状查询的时候,oracle有自己的优势,一条sql语句就可以搞定,而mysql这种数据库就只能用递归了... 递归的项目实例: //递归取到栏目路径 public List getTreeList ...

  4. Case of the Zeros and Ones 分类: CF 2015-07-24 11:05 15人阅读 评论(0) 收藏

    A. Case of the Zeros and Ones time limit per test 1 second memory limit per test 256 megabytes input ...

  5. 使用opencv自带的融合函数

    [wiki,blog]使用opencv自带的融合函数 [wiki,blog]使用opencv自带的融合函数 /*M/////////////////////////////////////////// ...

  6. HDU(2485),最小割最大流

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2485 Destroying the bus stations Time Limit: 40 ...

  7. android post请求

    参考文章:http://blog.csdn.net/lotusyangjun/article/details/22292445 http://blog.csdn.net/withiter/articl ...

  8. 华东交通大学2016年ACM“双基”程序设计竞赛 1003

    Problem Description 风雨漂泊异乡路, 浮萍凄清落叶飞. 游子寻根满愁绪,一朝故土热泪归.Hey ecjtuer! 刚刚学习了二叉树的知识,现在来考察一下..给你一个深度为h的满二叉 ...

  9. Android内存Context泄露:Handler&内部类

    1 public class SampleActivity extends Activity { 2 3 private final Handler mLeakyHandler = new Handl ...

  10. Redis的WEB界面管理工具phpRedisAdmin

    下载地址:http://down.admin5.com/php/75024.html 官方网址:https://github.com/ErikDubbelboer/phpRedisAdmin