V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
manyfreebug
V2EX  ›  JavaScript

绑定事件:addEventListener("事件名称",function(){},useCapture)第二个参数的疑问

  •  
  •   manyfreebug · 2019-03-08 21:16:32 +08:00 · 2887 次点击
    这是一个创建于 1847 天前的主题,其中的信息可能已经有所发展或是发生改变。
    通常可以这样给目标对象添加事件:
        element.addEventListener("事件名称",function(){},useCapture);
        
    1.其中第二个参数为一个函数。事件发生时,会调用该监听函数。请问是谁调用了这个函数?
    2.第二个参数除了可以是监听函数,还可以是一个具有 handleEvent 方法的对象:
        buttonElement.addEventListener('click', {
          handleEvent: function (event) {
            console.log('click');
          }
        });
      为什么还可以是一个具有 handleEvent 方法的对象,这个和第二个参数为一个函数时存在什么联系吗?    
    
    5 条回复    2019-03-09 02:00:43 +08:00
    molvqingtai
        1
    molvqingtai  
       2019-03-08 21:34:51 +08:00
    在 MDN 上找到答案了,还发现第三个参数还能是个对象
    https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
    nVoxel
        2
    nVoxel  
       2019-03-08 21:35:38 +08:00
    在学习发布订阅模式的时候也注意到了这一点。
    实际了解下发布订阅模式的实现,应该也就能理解了~

    至于使用 handleEvent 和直接传入一个函数的区别,可以看如下链接~
    https://stackoverflow.com/questions/41565028/comparison-between-passing-an-object-with-a-handleevent-property-and-traditional
    rabbbit
        3
    rabbbit  
       2019-03-08 22:06:15 +08:00
    谁调用了这个函数?

    js 是单线程的,也就是同一时间只能作一件事.
    当然这里的'单线程'是相对于 js 这门语言而言的,不是说 js 引擎 /宿主是单线程的.
    那事件是如何触发的呢?
    当触发一个事件时, 浏览器将事件的"回调函数"(也就是 addEventListener 的第二个参数)放进一个 task queue(事件队列)里.

    js 引擎有个 event loop.可以把它理解成一个无限的循环, 不停去的检查 task queue 里有没有东西.
    当"js 引擎"空闲的时候(call stack 为空),如果 task queue 里有东西, 就取一个出来运行.


    https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
    zzjas98
        4
    zzjas98  
       2019-03-09 01:47:57 +08:00
    一楼正解。搜了一些文章,发现 W3C standard 规定的是第二个参数要是一个 EventListener 的 object。但是历史原因大家都习惯直接给一个 function,所以浏览器为了兼容就两种方式都允许了,除了 bind 不同执行效果应该是一样的。
    同时发现一些文章讲使用 EventListern object 的好处。

    W3C AddEventListener: https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration
    W3C EventListener: https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener
    MDN EventListener: https://developer.mozilla.org/en-US/docs/Web/API/EventListener
    其他文章:
    https://medium.com/@photokandy/til-you-can-pass-an-object-instead-of-a-function-to-addeventlistener-7838a3c4ec62
    http://ajaxian.com/archives/an-alternative-way-to-addeventlistener


    TL;DR
    两者一样
    https://s3-us-west-1.amazonaws.com/zzjas/public/Image_laHTwqhWbC.png
    zzjas98
        5
    zzjas98  
       2019-03-09 02:00:43 +08:00
    我也有可能说反了😂实在没找到“给 function ”和“给 object ”哪个算是 legacy,既然现在的 w3c 说是用 object,我就猜“给 function ”是 legacy 了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   979 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 20:27 · PVG 04:27 · LAX 13:27 · JFK 16:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.