JS事件流

事件

HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。

事件流

事件流描述的就是从页面中接收事件的顺序。而早期的IE和Netscape提出了完全相反的事件流概念,IE事件流是事件冒泡,而Netscape的事件流就是事件捕获。

事件流类别

  • 事件冒泡
    • 即从下至上,从目标触发的元素逐级向上传播,直到window对象。
  • 事件捕获
    • 即从上至下,从document逐级向下传播到目标元素。

后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是上述二者的结合。 DOM2级事件规定的事件流包括三个阶段: + 事件捕获阶段 + 处于目标阶段 + 事件冒泡阶段 注意:warning::先捕获后冒泡,但是在目标节点上谁写在前面谁先执行。但是在目标元素上不区分冒泡还是捕获,按绑定的顺序来执行。

DOM事件级别

DOM0:不是W3C规范。

DOM0级事件具有极好的跨浏览器优势,会以最快的速度绑定。绑定方式有如下两种

  • 行内绑定(内联模型):

通过在JS中选中某个节点,然后给节点添加onclick属性

"btnClick()">按钮
<script>
function btnClick(){
    console.log("hello");
}
script>
复制代码
  • 动态脚本:

通过在JS中选中某个节点,然后给节点添加onclick属性

"btn">按钮
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
    console.log("点击");
}
script>
复制代码

DOM1:开始是W3C规范。专注于HTML文档和XML文档。

其中DOM1级事件处理标准中并没有定义事件相关的内容,所以没有所谓的DOM1事件处理

DOM2:对DOM1增加了 样式表对象模型

DOM2级定义了两个事件处理程序。(观察者模式)

  • addEventListener() ---添加事件侦听器
  • removeEventListener() ---删除事件侦听器

函数均有3个参数, 第一个参数是要处理的事件名 第二个参数是作为事件处理程序的函数 第三个参数是一个boolean值,默认false表示使用冒泡机制,true表示捕获机制。

"btn">按钮
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",hello,false);
btn.addEventListener("click",helloagain,false);
function hello(){
    console.log("hello");
}
function helloagain(){
    console.log("hello again");
}
script>
// 点击后结果: // hello// hello again
复制代码

如果定义了一模一样的监听方法时,是会发生覆盖的。

"btn">点击
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",hello,false);
btn.addEventListener("click",hello,false);
function hello(){
    console.log("hello");
}
script>
// 点击后结果: // hello
复制代码

DOM3:对DOM2增加了 内容模型 (DTD 、Schemas) 和 文档验证 。 对DOM2增加了 内容模型 (DTD 、Schemas) 和 文档验证 。定义了一些新的事件,比如键盘事件,还可以自定义事件。

自定义事件

自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。要创建的自定义事件可以由createEvent("CustomEvent"); 返回的对象有一个initCustomEvent()方法接收如下四个参数。

  • type:字符串,触发的事件类型,自定义。例如 “keyDown”,“selectedChange”;
  • bubble(布尔值):标示事件是否应该冒泡;
  • cancelable(布尔值):标示事件是否可以取消;
  • detail(对象):任意值,保存在event对象的detail属性中;

可以像分配其他事件一样在DOM中分派创建的自定义事件对象。如:

var  div = document.getElementById("myDiv");
EventUtil.addEventHandler(div,"myEvent", function () {
  alert("div myEvent!");
});EventUtil.addEventHandler(document,"myEvent",function(){
  alert("document myEvent!");
});if(document.implementation.hasFeature("CustomEvents","3.0")){
  var e = document.createEvent("CustomEvent");
  e.initCustomEvent("myEvent",true,false,"hello world!");
  div.dispatchEvent(e);}
复制代码

这个例子中创建了一个冒泡事件“myEvent”。而event.detail的值被设置成了一个简单的字符串,然后在div和document上侦听该事件,因为在initCustomEvent中设置了事件冒泡。所以当div激发该事件时,浏览器会将该事件冒泡到document。

阻止冒泡

stopPropagation函数

btn.addEventListener('click',function(ev){
    ev.stopPropagation();    console.log('阻止冒泡')
}, false)
复制代码

事件委托(事件代理)

  • 原理

如果有多个DOM节点需要监听事件的情况下,给每个DOM绑定监听函数,会极大的影响页面的性能,因为我们通过事件委托来进行优化,事件委托利用的就是冒泡的原理。

    <li>1li>
    <li>2li>
    <li>3li>
    <li>4li>
    <li>5li>

<script>
    var li_list = document.getElementsByTagName('li')
    for(let index = 0;index'click', function(ev){
            console.log(ev.currentTarget.innerHTML)
        })
    }
script>

复制代码

正常情况我们给每一个li都会绑定一个事件,但是如果这时候li是动态渲染的,数据又特别大的时候,每次渲染后(有新增的情况)我们还需要重新来绑定,又繁琐又耗性能;这时候我们可以将绑定事件委托到li的父级元素,即ul。

var ul_dom = document.getElementsByTagName('ul')
ul_dom[0].addEventListener('click', function(ev){  
    console.log(ev.target.innerHTML)
})
复制代码

target和currentTarget区别:

  • target返回触发事件的元素,不一定是绑定事件的元素
  • currentTarget返回的是绑定事件的元素

优点

  • 提高性能: 每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。
  • 动态监听: 使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • js --- 事件流

      事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

    小蔚
  • JS事件流

    有意思的是,当时不同的开发团队对于事件流提出了完全相反的概念,主要分为IE事件流——冒泡,Netscape Communicator事件流——捕获。

    流眸
  • JS事件流模型

    事件捕获Event Capturing是一种从上而下的传播方式,以click事件为例,其会从最外层根节向内传播到达点击的节点,为从最外层节点逐渐向内传播直到目标...

    WindrunnerMax
  • js事件流机制

    在JavaScript中事件流是指一个事件沿特定数据结构传播的一个过程。整个事件流总共包含三个阶段(从dome2来说):1.事件捕获阶段、2.处于事件目标阶段、...

    OECOM
  • JS中DOM事件流总结

    本文参照:https://segmentfault.com/a/1190000015603334

    前端小tips
  • js事件

    1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body...

    前朝楚水
  • JS事件篇

    浏览器加载一个页面时,是按照自上而下的顺序加载的,读取到一行就运行一行,如果将script标签写到页面上边,在代码执行的时候,页面还没有完全加载

    大忽悠爱学习
  • js --- 事件冒泡 事件捕获

      他们是描述事件触发时序问题的术语。事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件。绑定...

    小蔚
  • js鼠标事件

    PS:鼠标移动(onmousemove)和鼠标移入(onmouseover)区别:移动事件指鼠标只要移动就产生事件,移入事件需要移入到指定的对象内才执行事件

    十月梦想
  • js鼠标事件

    今天遇到一个非常奇怪而又搞笑的事情:给一个a标签添加一个鼠标移动上时给一个事件,我给其添加的是一个onMouseMove事件,结果在IE6 7 8 9和GOOL...

    小小许
  • js事件循环

    之前有看过一些事件循环的博客,不过一阵子没看就发现自己忘光了,所以决定来自己写一个博客总结下!

    嘿嘿嘿
  • js 事件笔记

    在Web中, 事件在浏览器窗口中被触发,执行事先绑定的事件处理器(也就是事件触发时会运行的代码块),对事件做出响应。 用户在浏览器的任何一个操作都会去触发一个事...

    bamboo
  • js事件委托

    事件委托也叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

    RobinsonZhang
  • Js拖拽事件

    田田田
  • js事件冒泡

    DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

    ZEHAN
  • js事件大全

    原文地址:http://www.cnblogs.com/weixu/archive/2007/09/06/884738.html

    乔达摩@嘿
  • JS 事件循环

    众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心,可...

    Umbrella1024
  • js委托事件 转

    document.getElementById("spec_area").addEventListener("click",function(e) {   /...

    双面人
  • js中的事件(event)

    我们可以简单的把事件理解为浏览器的感知系统。比如说:他可以感觉到用户是否点击(click)了页面、鼠标是否进入了页面的某个元素上面(mouseover或mous...

    山河木马

扫码关注云+社区

领取腾讯云代金券