三言两语之js事件、事件流以及target、currentTarget、this那些事

厉害了我的哥——你是如此简单我却将你给遗忘

  放假前再看某文档,里边提到两个我既熟悉又陌生的概念target、currentTarget,说他熟悉我曾经看到过这两个事件对象的异同处,说他陌生吧?很不巧。正要运用了,吾才发现吾压根就没记住。。。其实要讲清楚target、currentTarget,我们就不得不说一下事件流这个概念,而要言明事件流,我们也要晓得一下神马是事件以及一些周边生态概念,这三个概念是必须放在一块说,我们才能对能对这部分的知识有很好的理解滴,网上信息太零散,于是乎就有了这篇算我复习的博文吧!大牛略过,如我般的白菜们阅读完本文你将可以了解如下概念:

神马是事件,事件三种写法html事件处理程序、dom0级、dom2级

事件流是什么鬼及其运用和使用上的坑~   

target、this、currentTarget的区别

厉害了我的哥——事件

  我们先聊聊事件,首先我们必须明确一点,事件通常与函数挂钩。要聊事件这个名词,我先扯下js,我们都知道js由ECMA、DOM、BOM组成,ECMA为js的基本语法,如果你实在不知道是啥,可以简单的理解为他规定了循环是用for关键字,而采用var来定义一个变量,诸如此类;BOM是浏览器对象模型的缩写,即用我们的js来操作浏览器;DOM是文档对象模型的缩写,那啥子是文档呢?简单可以这样理解——我们的html标签在被浏览器渲染的时候会生成一棵标签树,我们可以把这颗由标签构成的树别名称之为文档树或者文档,而每一个标签在js中都可以被抽成一个对象,so,到此你应该已了然于胸了吧?原来文档对象模型可以简单的理解为html标签文档在js中的对象映射,也就是有了dom这个概念,我们可以在js中操作html的元素咯,如图所示:

<html>
    <head>
    </head>
    <body>
        <div>
        </div>
    </body>
</html>

当我们在源文件中写下如上的代码,浏览器会解析成如图所示

如果把浏览器当作最顶层容器,抽象成文字可以理解为

window-》dowument-》html-》head/body-》其他元素

这个层级关系就可以理解为文档树了,现在我们可以得出如下几个概念:

  1. 凡出现在html中的标签被浏览器解析的时候都会被挂载到dom树上。
  2. dom树上的每个标签都是一个独立的对象,既然是对象就会有属性和方法,上文也提到过事件通常与方法不离不弃,所以这里我们就会晓得一个基本常识了,事件一般会和标签和方法挂钩,嗯是的!我们通常在标签上注册一个事件,当事件满足条件被触发以后就会执行我们早些预定义好的方法。
  3. 事件的概念就是:让html在某些特定条件下执行了一段js脚本,某些特定的条件就是如单击,双击,鼠标经过等,这些条件以属性的形式呈现在html代码中,而触发执行的js脚本则通常为方法,如代码:
<div onclick = "fn()"></div>

<script>
    funcrion fn(){
        alert("我被单击了");
    }
</script>

onclick为某些条件的事件句柄,fn为事件满足条件后要执行的函数,以上只是事件的一种写法,不足以应付开发,为此我们还需要了解下常见事件的几种写法:

这里我们需要了解三种,分别为最原始的html混合事件写法,dom0级写法、dom2级写法:

  1. 最原始的写法:和html混合在一起写,缺点是代码高冗余,且无法添加多个事件处理函数如上文对事件的举例则为典型的**html事件处理程序*写法
  2. dom0级:将html代码和js代码分离,且支持匿名函数,可以看到完美的改进了1的冗余缺憾,所有的事件相关操作都在js中完成
    //html代码
    <div id="a"></div>
    
    //js代码
    var div1 = document.getElementById("a");
    a.onclick=function(){
       alert("我被单击了");
    }
    
  3. dom2级:ie使用attachEventListener其他非ie使用addEventListener,可以支持绑定多个事件,瞧吧,又一个缺憾被完美解决了~,而且dom2级还可以自定义事件流,好,到这里大家留个心,这是第二部分我们要介绍的重点。牢记这个名词于心哦~
  4. dom3级:对事件进行了更广而全的分类,请大家自行查阅。

厉害了我的哥——事件流

  接上,事件我们已经晓得是什么鬼了,现在多了个流,组个词人流,水流,流向,额貌似靠近点它的本意了,总有点排队方向的感脚,没错,很正确的第n感。事件流官网定义:描述的是从页面中接收事件的顺序,那~~~是谁从页面接收事件的顺序呢?接收的顺序有啥子呢?接收的范围呢?
  咳咳,回答一下上边的问题呗,谁接收?你说呢?一点头绪还没有的童鞋建议重新看下上文吧,接收的顺序和范围,噗,这是接下来要说道说道的了:

接收顺序(事件流方式),需要我们了解:
1. 事件捕获:什么叫捕获,其实不用扯那么多一句话从最不具体的到最具体的
2. 事件冒泡:什么叫冒泡,正好和上面相反,从最具体的到最不具体的
3. 为什么会有两种事件流方式呢?历史原因,ie提出的是事件冒泡,而w3c提出的是事件捕获。
4. 现代浏览器高级了,那。。。。。嗯,我知道你要问啥,你一定要问浏览器内部是如何解析这两种事件流的,它的执行顺序:事件捕获-》目标阶段-》事件冒泡,一句话就是先捕获后冒泡

捕获和冒泡的范围呢?也就是接收事件的范围呢? 哈哈,这个上面其实我已经说过了:

window-》dowument-》html-》head/body-》div或其他元素
注意昂,现在的浏览器都是从window开始滴,不管冒泡还是捕获其的传递范围一定是父子关系,也就是外层到内层,或者从内层到外层。假设我们给div添加一个事件方法,如果是事件捕获的话是从window开始,因为他是最不具体的元素,如果是冒泡的话则是从div开始,所以这里的具体不具体是相对于添加事件的元素而言的,说到这里,大家一定要晓得,我们要使用事件流通常要配合dom2级事件去写,要是读到这里你还不了解这个,那宝宝就让你气死鸟~哦,还要知道的一点我们现开发中多使用的事件流通常是冒泡,嗯这点随了ie了,但是要注意现在的主流浏览器默认就是冒泡,但通常我们在使用addEventListener这个方法的时候他的第三个参数还是会显示的指定为false,即为不捕获**。

  防着有人不理解,我多解释几句呗,捕获和冒泡的方式决定着浏览器何时去处理这个事件,如果我把事件声明在冒泡阶段处理,那么在捕获阶段即使捕获到了这个事件,事件也是不会被执行滴,这就是他的一个重要运用,这点也是经常被大家混淆和忽略的地方,但恰好也是它最好玩的地方。随意给大家从网上找两张万年错且没什么卵用的图,说他错是因为现在的事件范围是从window开始的,结果网上的很多图都是画到了document,如下图:
冒泡流程图

捕获流程图

事件流使用上最好玩的地方,也正是其最大的坑,大家看如下例子,

<div id="one">
    <div id="two">
        <div id="three"></div>
    </div>
</div>

one.addEventListener(‘click‘,function(e){
    console.log(‘one‘);
},false);

two.addEventListener(‘click‘,function(e){
    console.log(‘two‘);
},false);

three.addEventListener(‘click‘,function(e){
    console.log(‘three‘);
},true);

使用的是dom2级中的非ie方法,从代码中可以看到one和two为冒泡,three为捕获,所以事件的执行结果就会被改变,我相信很多童鞋若不看小弟这篇软文直接晕菜了吧?但是看到这里的你,一定会有一种say爽的感觉,当我们点击最里面的div的时候,打印数序应该为three->two->one。一句话总结:现代的浏览器对事件的处理方式为先捕获后冒泡,只要有事件就会按这个顺序执行,雷打不动滴,雷打不动滴。dom2级决定的只是只是只是在事件流的哪个时机去执行处理函数而已而已。

  温故而知新啊~上文说到ie使用attachEventListener其他非ie使用addEventListener,且dom2级可以添加多个事件,我们都知道ie使用的是是冒泡也就是从具体到不具体,而非ie为捕获也就是从不具体到最具体,当我们要绑定多个事件处理函数的时候,事件处理函数的顺序ie和非ie在默认情况下是不一致的,因为他们两个的事件流默认情况下是正好相反的,这在不指定事件流参数的情况下确实是个坑~

厉害了我的哥——target、this、currentTarget的区别

  现在终于到了target、this、currentTarget

先诉重点理论:
1. target:触发事件的某个具体对象,只会出现在事件流的目标阶段(谁触发谁命中,所以肯定是目标阶段)
2. currentTarget:绑定事件的对象,恒等于this,可能出现在事件流的任意一个阶段中
3. 通常情况下terget和currentTarget是一致的,我们只要使用terget即可,但有一种情况必须区分这三者的关系,那就是在父子嵌套的关系中,父元素绑定了事件,单击了子元素(根据事件流,在不阻止事件流的前提下他会传递至父元素,导致父元素的事件处理函数执行),这时候currentTarget指向的是父元素,因为他是绑定事件的对象,而target指向了子元素,因为他是触发事件的那个具体对象,如下代码和截图所示:

<div id="one">
   <div id="three"></div>
</div>

one.addEventListener(‘click‘,function(e){
    console.log(e.target);  //three
    console.log(e.currentTarget);  //one
},false);

时间: 2024-08-04 02:23:24

三言两语之js事件、事件流以及target、currentTarget、this那些事的相关文章

JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理

1.JS里面的事件流 DOM2级事件模型中规定了事件流的三个阶段:捕获阶段.目标阶段.冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素接收,逐级向下,传播到最具体的元素. 冒泡事件流:IE提出的事件流,即事件由最具体的元素接收,逐级向上,传播到页面. 关于js事件,这里有一篇非常详细的介绍,可以看下:http://www.cnblogs.com/hyaaon/p/4630128.html 2.IE和W3C不同绑定事件解绑事件的方法

js阻止浏览器、元素的默认事件与js阻止事件冒泡、阻止事件流

嵌套的div元素,如果父级和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,下面介绍一下js阻止默认事件与js阻止事件冒泡示例,大家参考使用吧 1. event.preventDefault();  -- 阻止元素的默认事件.注:a元素的点击跳转的默认事件 , button,radio等表单元素的默认事件 , div 元素没有默认事件 例: 复制代码代码如下: <a href="http://www.baidu.com" target="_bl

JS的事件流的概念(重点)

在学习jQuery的事件之前,大家必须要对JS的事件有所了解.看下文 事件的概念 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件.想要知道这些事件是在什么时候进行调用的,就需要了解一下"事件流"的概念. 什么是事件流 事件流描述的是从页面中接收事件的顺序 1.DOM事件流 "DOM2级事件"规定的事件流包括三个阶段: ① 事件捕获阶段: ② 处于目标

Js 冒泡事件阻止

原文:Js 冒泡事件阻止 1. 事件目标 现在,事件处理程序中的变量event保存着事件对象.而event.target属性保存着发生事件的目标元素.这个属性是DOM API中规定的,但是没有被所有浏览器实现 .jQuery对这个事件对象进行了必要的扩展,从而在任何浏览器中都能够使用这个属性.通过.target,可以确定DOM中首先接收到事件的元素(即实际被单击的元素).而且,我们知道this引用的是处理事件的DOM元素,所以可以编写下列代码:$(document).ready(function

Atitit. &#160;Js 冒泡事件阻止&#160;事件捕获&#160;&#160;&#160;事件传递 &#160;事件代理

Atitit.  Js 冒泡事件阻止 事件捕获   事件传递  事件代理   1. 事件冒泡1 2. 事件捕获1 3. 同时支持了事件捕获阶段和事件冒泡阶段ddEventListener的第三个参数1 4. 事件代理3 5. 冒泡还是捕获?3 6. Js 冒泡事件阻止3 6.1. 返回false5 7. 事件冒泡 使处理函数有范围较大的触发面积,在“拖拽效果”脚本中是必须的5 8. refe6 8.1.1. 浅谈事件冒泡与事件捕获 - ac黄博客精选 - SegmentFault6   1. 事

JS的事件模型

之前对事件模型还是比较清楚的,许多概念都清晰映射在脑海中.工作之后,一方面使用的 局限性,二是习惯于用框架中的各种事件监听方式,简单即方便,久而久之,事件的一些概念开 始淡出记忆中,就像我现在已经开始淡忘C语言的指针.麦克斯韦方程组.矩阵的变换.最小二乘 法等.知识就像五彩缤纷的鹅卵石铺垫在你前行的道路上,从简单到深刻,从深刻到领悟,一直 助你渐行渐远.回头看看事件模型呗. 一.事件简简介事件包括:鼠标事件键盘事件框架事件 onerror onresize onscroll等表单事件事件 onb

JS中事件代理与委托

在javasript中delegate这个词经常出现,看字面的意思,代理.委托.那么它究竟在什么样的情况下使用?它的原理又是什么?在各种框架中,也经常能看到delegate相关的接口.这些接口又有什么特殊的用法呢?这篇文章就主要介绍一下javascript delegate的用法和原理,以及Dojo,jQuery等框架中delegate的接口. JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的

初步理解JS的事件机制

一.事件流(捕获,冒泡) 事件流:指从页面中接收事件的顺序,有冒泡流和捕获流. 当页面中发生某种事件(比如鼠标点击,鼠标滑过等)时,毫无疑问子元素和父元素都会接收到该事件,可具体顺序是怎样的呢?冒泡和捕获则描述了两种不同的顺序. DOM2级事件规定事件流包括三个阶段,如图: 假如我们点击一个div, 实际上是先点击document,然后点击事件传递到div,而且并不会在这个div就停下,div有子元素就还会向下传递,最后又会冒泡传递回document,如上图 为了兼容更多的浏览器,非特殊情况一般

js冒泡事件

一.什么是事件冒泡 在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处 理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它 被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window). 打个比方说:你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省

JS:事件委托

事件委托 事件流 事件流描述的是从页面中接收事件的顺序.---JS高级程序设计(第3版) DOM Level 2 Events规定的事件流有三个阶段:①事件捕获阶段.②处于目标阶段.③事件冒泡阶段 事件委托 当需要添加的事件过多时,可以使用事件委托,而事件委托实际上利用了事件冒泡的特性. 使用事件委托还需了解事件对象(event):在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息. 在此仅需知道在DOM标准中,event拥有一个target属性表示事