最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    正文概述 掘金(saucxs)   2021-01-24   481

    关注「松宝写代码」,精选好文,每日一题

    2020,实「鼠」不易

    2021,「牛」转乾坤

    风劲潮涌当扬帆,任重道远须奋蹄!

    一、前言

    2020.12.23 立的 flag,每日一题,题目类型不限制,涉及到JavaScript,Node,Vue,React,浏览器,http等领域。

    本文是【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    这是一道很宽泛的题目,如何回答更有亮点?

    昨天的题目号码写错了,在这里做个说明。

    【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    二、目录

    • 事件流
    • 事件处理程序
      • HTML事件处理程序
      • DOM0级事件处理程序
      • DOM2级事件处理程序
      • IE事件处理程序
      • 跨浏览器实现事件处理程序
    • 事件对象 Event
      • DOM中的事件对象
      • IE中的事件对象
      • 跨浏览器的事件对象

    1、事件流

    事件流描述的是从页面中接收事件的顺序。

    事件冒泡流

    IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。所有的现代浏览器都支持事件冒泡。

    事件捕获流

    Netscape Communicator团队提出的事件流叫做事件捕获(event capturing),即事件开始时由不太具体的节点接收,而最具体的节点应该最后收到事件。

    DOM2级事件

    DOM2级事件规定事件流分为三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

    2、事件处理程序

    响应事件的函数称为事件处理程序。

    HTML事件处理程序

    在元素中使用事件处理程序,如:

    <input id="btn" type="button" value="Button" onclick="alert(event.type)">
    
    • 使用该方式绑定的事件,在事件函数中存在一个局部变量event,用来保存事件对象。
    • 该方式存在的缺点:
      • 1、JavaScript与HTML加载顺序的不确定性,可能在JavaScript未加载完成之前就触发相应的事件,产生错误。
      • 2、作用域连在不同的浏览器中会导致不同的结果。
      • 3、JavaScript与HTML代码的紧密耦合,如果需要更换事件处理程序,则需要更改两个地方。

    DOM0级事件处理程序

    第四代web浏览器中出现的方法,现在仍被个浏览器所支持。实现方式为将函数赋值给一个事件处理程序属性。

    <input id="btn" type="button" value="Button">
    
    let btn = document.getElementById('btn')
    // 添加事件,多次定义后,最后一个将覆盖之前的定义
    btn.onclick = function () {
      alert(this.id)
    }
    // 删除事件
    btn.onclick = null
    

    使用该方式绑定的事件,在事件函数中可以使用this访问元素的任何属性和方法,且在事件流的冒泡阶段被处理。

    DOM2级事件处理程序

    提供了两个方法addEventListener()removeEventListener()分别用来指定和删除事件处理程序。所有的DOM节点都包含这两个方法。

    接收三个参数:

    • 事件名
    • 事件处理程序的函数
    • 布尔值,默认值为false。 true: 在捕获阶段调用事件处理程序; false: 冒泡阶段调用事件处理程序
    <input id="btn" type="button" value="Button">
    
    let btn = document.getElementById('btn')
    
    function fn ( ) {
       alert('This is a function')
    }
    
    // 添加事件,可以定义多个,按照顺序执行
    btn.addEventListener('click', function () {
      alert('click1')
    }, false)
    btn.addEventListener('click', fn, false)
    
    // 删除事件
    btn.removeEventListener('click', fn)
    
    • 使用addEventListener添加的事件处理程序只能由removeEventListener删除,移除时与传入的三个参数必须完全相同。
    • removeEventListener无法移除匿名函数。

    IE事件处理程序

    与DOM2级类似,也提供了两个方法attachEvent()detachEvent()分别用来指定和删除事件处理程序。所有的DOM节点都包含这两个方法。

    使用attachEvent()添加的事件处理程序,均在冒泡阶段被处理。

    接收两个参数:

    • 事件名
    • 事件处理程序的函数
    <input id="btn" type="button" value="Button">
    
    let btn = document.getElementById('btn')
    
    function fn ( ) {
       alert('This is a function')
    }
    
    // 添加事件,可以定义多个,按照相反的顺序执行
    btn.attachEvent('onclick', function () {
      alert('click1')
    })
    btn.attachEvent('onclick', fn)
    
    // 删除事件
    btn.detachEvent('onclick', fn)
    

    与其他类型方法的区别

    • 1、主要区别是事件处理程序的作用域。在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中进行,this等于window。
    • 2、第一个参数必须是on + 事件名的形式。
    • 3、添加多个事件处理程序时,不是按照顺序依次执行,而是以相反的顺序执行。

    跨浏览器实现事件处理程序

    • 创建一个EventUtil对象
    • 为EventUtil对象实现两个方法:addHandler()、removeHandler()
    • 以下示例的方法,还需要注意作用域的问题
    let EventUtil = {
      addHandler: function (el, type, handler) {
        if (el.addEventListener) {
           el.addEventListener(type, handler, false)
        } else if (el.attachEvent) {
           el.attachEvent('on' + type, handler)
        } else {
           el['on' + type] = handler
        }
      },
      removeHandler: function (el, type, handler) {
        if (el.addEventListener) {
             el.removeEventListener(type, handler, false)
          } else if (el.attachEvent) {
             el.detachEvent('on' + type, handler)
          } else {
             el['on' + type] = null
          }
      }
    }
    

    3、事件对象 Event

    触发DOM事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。包括导致事件的元素、事件类型以及其他与特定事件相关联的信息。

    DOM中的事件对象

    兼容DOM的浏览器会将event对象传入到事件处理器中。触发的事件类型不一样,可以用的方法和属性也不一样。

    所有的事件的event对象都包含以下属性和方法:

    属性/方法类型读/写说明
    bubblesBoolean只读事件是否冒泡cancelableBoolean只读是否可以取消事件的默认行为currentTargetElement只读事件处理程序当前正在处理的元素defaultPreventedBoolean只读为true时,表示已经调用了preventDefault()detailInteger只读与事件相关的细节信息eventPhaseInteger只读调用事件处理程序的阶段:1 捕获阶段;2:目标阶段;3:冒泡阶段preventDefaultFunction只读取消事件的默认行为,cancelable === true时,可使用该方法stopImmediatePropagation()Function只读取消事件的进一步捕获或者冒泡,同时阻止任何事件处理程序被调用stopPropagation()Function只读取消事件的进一步捕获或者冒泡, bubbles === true时,可以使用该方法targetElement只读事件的目标trustedElement只读true: 事件由浏览器生成;false:开发人员通过JS创建typeString只读事件的类型viewAbstractView只读与事件关联的抽象试图。等同于发生事件的window对象

    说明

    • target 触发事件的真是目标
    • currentTarget 事件处理程序内部 this===currentTarget
    • 只有在事件处理程序执行期间,event对象才会存在;一旦事件处理程序执行完成,event对象就会被销毁。

    IE中的事件对象

    指定事件处理程序的方法不同,获取event对象的方式也不同。

    • DOM0级 使用window.event获取event对象
    • 使用attachEvent()方式添加,会有一个event对象作为参数被传入事件处理程序,当然在这种情况下,也可以通过window对象来获取event对象。

    所有的事件的event对象都包含以下属性和方法:

    属性/方法类型读/写说明
    cancelBubblesBoolean读/写默认false,true:可以取消事件冒泡,与DOM中的stopPropagation()方法相同returnValueBoolean读/写默认true,false:取消事件的默认行为,与DOM中的preventDefault()方法相同srcElementElement只读事件的目标,与DOM中的target属性相同typeString只读事件的类型

    说明

    • 因为事件处理程序的作用域是根据指定它的方式来确定的,所以最好使用srcElement来确定事件目标。

    跨浏览器的事件对象

    针对IE与DOM事件的差异,可以继续补充前面创建的EventUtil对象,解决兼容性问题。

    let EventUtil = {
      addHandler: function (el, type, handler) {
        if (el.addEventListener) {
           el.addEventListener(type, handler, false)
        } else if (el.attachEvent) {
           el.attachEvent('on' + type, handler)
        } else {
           el['on' + type] = handler
        }
      },
      removeHandler: function (el, type, handler) {
        if (el.addEventListener) {
             el.removeEventListener(type, handler, false)
          } else if (el.attachEvent) {
             el.detachEvent('on' + type, handler)
          } else {
             el['on' + type] = null
          }
      },
      // ------- 新增加的关于事件对象的兼容性处理 --------
      getEvent: function (event) {
        return event ? event : window.event
      },
      getTarget: function (event) {
        return event.target || event.srcElement
      },
      preventDefault: function (event) {
        // 阻止事件的默认行为
        if (event.preventDefault) {
          event.preventDefault()
        } else {
          event.returnValue = true
        }
      },
      stopPropagation: function (event) {
        // 阻止冒泡
        if (event.stopPropagation) {
          event.stopPropagation()
        } else {
          event.cancelBubbles = true
        }
      }
    }
    

    谢谢支持

    1、文章喜欢的话可以「分享,点赞,在看」三连哦。

    2、作者昵称:saucxs,songEagle,松宝写代码。「松宝写代码」公众号作者,每日一题,实验室等。一个爱好折腾,致力于全栈,正在努力成长的字节跳动工程师,星辰大海,未来可期。内推字节跳动各个部门各个岗位。

    3、长按下面图片,关注「松宝写代码」,是获取开发知识体系构建,精选文章,项目实战,实验室,每日一道面试题,进阶学习,思考职业发展,涉及到JavaScript,Node,Vue,React,浏览器,http,算法,端相关,小程序等领域,希望可以帮助到你,我们一起成长~

    【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    字节内推福利

    • 回复「校招」获取内推码
    • 回复「社招」获取内推
    • 回复「实习生」获取内推

    后续会有更多福利

    学习资料福利

    回复「算法」获取算法学习资料

    往期「每日一题」

    1、JavaScript && ES6

    • 第 28 题:【每日一题】(28题)面试官:原型链与构造函数结合方法继承与原型式继承的区别?

    • 第 22 题:【每日一题】(22题)面试官问:var与const,let的主要区别是什么?

    • 第 21 题:【每日一题】(21题)面试官问:谈谈JS中的 this 的绑定?

    • 第 20 题:【每日一题】(20题)面试官问:谈谈JS中的 webSockets 的理解?

    • 第 19 题:【每日一题】面试官问:谈谈JS中的 XMLHttpRequest 对象的理解?

    • 第 18 题:【每日一题】面试官问:JS中的 Ajax 跨域与扩展 Comet ?

    • 第 17 题:【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    • 第 16 题:【每日一题】面试官问:JS中如何全面进行客户端检测?

    • 第 15 题:【每日一题】面试官问:JS类型判断有哪几种方法?

    • 第 14 题:【每日一题】面试官问:谈谈你对JS对象的创建和引申

    • 第 13 题[每日一题]面试官问:['1', '2', '3'].map(parseInt)输出,原因,以及延伸?

    • 第 12 题[每日一题]面试官问:JS引擎的执行过程(二)

    • 第 11 题[每日一题]面试官问:JS引擎的执行过程(一)

    • 第 10 题[每日一题]面试官问:详细说一下JS数据类型

    • 第 8 题[每日一题]面试官问:谈谈你对ES6的proxy的理解?

    • 第 7 题[每日一题]面试官问:for in和for of 的区别和原理?

    • 第 6 题[每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?

    • 第 3 道「「每日一题」面试官问你对 Promise 的理解?可能是需要你能手动实现各个特性」

    • 第 2 道「[每日一题]ES6 中为什么要使用 Symbol?」

    2、浏览器

    • 第 9 题[每日一题]requestAnimationFrame不香吗?

    3、Vue

    • 第 5 道「每日一题」到底该如何回答:vue数据绑定的实现原理?

    4、HTML5

    • 第 29 道【每日一题】(29题)面试官:HTML-HTML5新增标签属性的理解?

    5、算法

    • 第 31 道[【每日一题】(31题)面试官:你对图论了解多少?(一)

    • 第 27 道【每日一题】(27题)算法题:如何使用多种解决方案来实现跳一跳游戏

    • 第 26 道【每日一题】(26题)算法题:最长公共前缀?

    • 第 25 道【每日一题】(25题)算法题:堆数据结构-前 K 个高频元素?

    • 第 24 道【每日一题】(24题)算法题:贪心算法-环游世界之如何加油?

    • 第 4 道「每日一题」与面试官手撕代码:如何科学高效的寻找重复元素?

    6、Node

    • 第 23 道【每日一题】(23题)面试官问:详细描述事件循环Event Loop?

    7、Http

    • 第 1 道「一道面试题是如何引发深层次的灵魂拷问?」

    起源地下载网 » 【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元