zoukankan      html  css  js  c++  java
  • DOM事件流

    一直以来,在DOM中添加事件总是使用三种方法,

    第一种使用HTML中的事件处理程序例如:

    <button onclick=' $$ '></button>

    第二种:使用在JavaScript中添加事件处理程序:

    var s =document.getElementById('id');
    s.oncilck=function(){}

    第三种使用 addEventListener 方法注册事件处理程序:

    document.getElementById('id').addEventListener('click',function(){})//注意是click

    一直是这样用的,却没有理解使用的弊端和注意的问题,现在总结一下这三者DOM事件处理方法的优劣。

    一、事件流

    事件流有两种,事件冒泡事件捕获,它表示当用户触发了某个页面元素的动作,应该由怎样的方式向“观察者”传递;就像是身为校长的你,学生发生了一起斗殴事件,你是通过挨个年级-班级去找到滋事者(事件捕获);还是通过一个学生主动告诉你事情发生的经过(事件冒泡);某种程度上,中国写信的地址方式和美国的写信的地址,有些类似冒泡和捕获的过程。

    1、事件冒泡

    假如一篇文档的结构:

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

    当点击div元素 ,触发了click事件,那么冒泡传递的方式是这样的,

    2、事件捕获

    自然是反方向的:

    3、DOM事件流

    很多面试会有问到这个问题,实际上DOM事件流是DOM2级事件中规定的,它包括,事件捕获阶段,目标发生阶段,和事件冒泡阶段。

     

    值得注意的是,div元素不会在捕获阶段接受事件,也就是捕获的过程到body后就停止了,接下来是目标阶段;在事件处理中属于冒泡阶段的一部分,

     DOM2中规定捕获阶段不会设计目标事件,但是高版本浏览器没有遵循规定;因此就有两个机会在目标对象中操作事件。

     二、事件处理程序

    事件的名称 click ;load;mouseover;事件处理程序以‘on’开头;因此click事件的事件处理程序就是onclickload事件的事件处理程序就是onload

    1、HTML事件处理程序

     HTML事件处理程序可以直接在事件处理程序中,添加执行的函数,也可以进行调用其他地方定义的脚本;

    <button oncilck="alert('hello world!')"></button>//执行代码直接添加到事件中
    <script>
    function hello(){
    alert('hello,world!')
    }
    </script>
    
    <button onclick='hello()'></button>//调用其他脚本

    HTML事件处理程序优点

    • 会创建一个封装着元素属性值的函数,这个函数中有一个局部变量event,也就是事件对象。
    <input type='button' value='click me' onclick='alert(this.value)'>//click me this值指向发生事件的目标元素;
    <input type='button' value='click' onclick='alert(event.type)'>//click 通过event对象可以访问事件对象;

    HTML事件处理程序缺点

    • 失去响应。如果定义的脚本在触发事件元素的后面进行定义的,很可能在没有加载脚本之前;用户点击了元素,会失去响应;(JavaScript引擎是逐行读取代码的)
    • HTML与JavaScript高度耦合,缺乏可维护性和增加维护成本。

    2、DOM 0 级事件处理程序

    JavaScript中常见的处理事件的方式,通过将函数赋值给一个事件处理程序属性;简单,而且跨浏览器;

    var but=document.getElementById('id');
    but.onclick=function(){
        alert(this.value)
    }

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

    but.onclick=null;//阻止事件处理的方式,设置null;

    3、DOM 2级事件处理程序

    通过addEventListener()    removeEventListener(),方法注册和删除事件处理程序,接受3个参数,事件名,处理函数,布尔值;

    var but=document.getElementById('id');
    but.addEventListener('click',function(){
        alert('this.value');
    },false);

    布尔值true表示在事件流捕获阶段触发调用,布尔值false 表示在冒泡阶段调用事件处理程序。

    注意:

    • 第二个参数是事件名,不是事件处理函数名, ‘click’而不是‘onclick’,与前两个方式不同。
    • 可以添加多个事件处理程序;处理的顺序按照注册的顺序执行。
    var but=document.getElementById('id');
    but.addEventListener(
    'click',function(){ alert('this.value'); },false);
    but.addEventListener(
    'click',function(){ alert('hello world'); },false);
    • 匿名函数无法通过removeEventListener()方法移除事件处理程序,因为两次的匿名函数不是同一个函数,
    var but=document.getElementById('id');
    
    but.addEventListener('click',function(){
        alert('hello world');
    },false);
    
    but.removeEventListener('click',function(){
        alert('hello world');
    },false);//无效,因为第二个参数是完全不同的匿名函数,只是定义相同;
    var but=document.getElementById('id');
    
    function hello(){
        alert('hello world')
    }
    
    but.addEventListener('click',hello,false);
    but.removeEventListener('click',hello,false)//有效,使用相同函数

    4、IE事件处理程序

    IE使用attachEvent()  detachEvent()两个方法添加事件处理,这两个方法分别接受两个参数,事件处理名称,事件处理函数;由于IE8更早版本只支持事件冒泡,因此通过attachEvent() 添加的时间处理程序会被添加到冒泡阶段。
    注意

    • attachEvent() 第一个参数是“onclick” 而不是“click”;
    • attachEvent() 也可以添加多个事件,不过执行的顺序完全相反;
    • 可以通过 detachEvent() 方法移除事件,和removeEventListener() 类似;不能移除匿名函数。
    var but=document.getElementById('id');
    function hello(){
        alert('hello world')
    }
    
    but.attachEvent('onclick',hello);
    but.attachEvent('onclick',function(){
        alert('this.id')
    })
    //先 弹出id ,后弹出 hello world
  • 相关阅读:
    自动化测试之读取配置文件 | 踩坑指南
    文未有福利 | BAT 名企大厂做接口自动化如何高效使用 Requests ?
    高效能 Tester 必会的 Python 测试框架技巧
    移动自动化测试从入门到高级实战
    1 天,1000+ 测试工程师分享了这个课程 | 年度福利
    H5性能分析实战来啦~
    接口测试实战 | Android 高版本无法抓取 HTTPS,怎么办?
    实战 | 接口自动化测试框架开发(Pytest+Allure+AIOHTTP+用例自动生成)
    第一期线上沙龙PPT领取方式
    Java日志第48天 2020.8.24
  • 原文地址:https://www.cnblogs.com/engeng/p/8862893.html
Copyright © 2011-2022 走看看