问题描述:
在创建网页的时候,我有一个困惑,我注意到有很多元素等待点击,所以我想问:哪种做法对性能更好?
为文档添加事件侦听器,然后检查我单击的元素的类或 id:
document.addEventListener('click', e => {
let element = e.target.id;
if(element === navbarBtn) /* do something */;
if(element === goUpBtn) /* do something */;
if(element === darkModeSwitcherBtn) /* do something */;
})
或
为我将单击的每个元素添加事件侦听器:
navbarBtn.addEventListener('click', () => {
// doing something
})
goUpBtn.addEventListener('click', () => {
// doing something
})
darkModeSwitcherBtn.addEventListener('click', () => {
// doing something
})
解决思路一:
这里的另一个人给了你一个解决方案来找出哪个更快,但我会采取不同的方向,因为我认为你误解了你真正应该寻找的东西。后者几乎肯定会更好,不管你能找到什么小的性能差距。这有几个关键原因:
-
阅读之前的代码,我问自己当这个事件触发时会发生什么?答案是我不知道,同一个函数中发生了太多事情。要调试此事件,我需要弄清楚哪个案例甚至失败以及触发它的原因。从节省开发人员在解决方案上花费的时间的角度来看,这是低效的。
-
如果您使用前一种解决方案,如果用户单击的不是 navBarBtn、goUpBtn 或 darkModeSwitcherBtn 会发生什么?您可能想象的答案是事件触发并检查每个条件,这再次使代码容易发生奇怪的交互,特别是如果您稍后添加其他事件。此外,从性能的角度来看,这也很糟糕,因为您正在不必要地调用函数和检查条件。
-
存在标准解决方案,它是为您需要事件的每个元素添加一个事件侦听器。这是一个非常常见的约定,您应该尽可能地遵守它,如果有的话只是因为它是其他人所期望的,以及您将在野外发现的其他代码将如何运行。必要时肯定有打破约定的空间,但是遵循这样的约定将使您在以后的阶段更容易使用其他人的代码。
简而言之,性能在这个问题上是一个红鲱鱼,并且是过早优化的一个非常明显的例子。这实际上不是您在这里应该关心的,因为与您可能不得不调试尝试做太多事情的函数相比,它对整体性能的影响非常小。
解决思路二:
这实际上取决于您如何定义better,因为它非常主观。
您绝对不想做的一件事是,每次有人单击您页面上的某些内容时都运行您的函数。这是非常低效的,好的代码是高效的代码。
从可读性的角度来看,您想要应用到按钮的功能也附加到该按钮上,这一点也更加清晰。如果您将所有内容都附加到 with 子句中,那么以后将是eventListeners
一场document
噩梦switch
。
从性能的角度来看,嗯。我想会document
稍微快一点,这只是由于 DOM 的工作方式、冒泡等原因,但是节省的时间(可能是 1 毫秒)将立即用于元素检查。
坚持eventListeners
在你正在使用的元素上使用,除非你绝对需要它在父元素上以利用事件委托,在这种情况下,它应该尽可能接近需要委托的元素。
解决思路三:
以上仅为部分解决思路,添加下方公众号后回复001,即可查看全部内容。公众号有许多评分最高的编程书籍和资讯,无套路,可放心使用
如果您觉得有帮助,可以关注公众号——立志于成为对程序员有益的公众号