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

2019-03-08 21:16:32 +08:00
 manyfreebug
通常可以这样给目标对象添加事件:
    element.addEventListener("事件名称",function(){},useCapture);
    
1.其中第二个参数为一个函数。事件发生时,会调用该监听函数。请问是谁调用了这个函数?
2.第二个参数除了可以是监听函数,还可以是一个具有 handleEvent 方法的对象:
    buttonElement.addEventListener('click', {
      handleEvent: function (event) {
        console.log('click');
      }
    });
  为什么还可以是一个具有 handleEvent 方法的对象,这个和第二个参数为一个函数时存在什么联系吗?    
2978 次点击
所在节点    JavaScript
5 条回复
molvqingtai
2019-03-08 21:34:51 +08:00
在 MDN 上找到答案了,还发现第三个参数还能是个对象
https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
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
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
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
2019-03-09 02:00:43 +08:00
我也有可能说反了😂实在没找到“给 function ”和“给 object ”哪个算是 legacy,既然现在的 w3c 说是用 object,我就猜“给 function ”是 legacy 了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/542639

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX