避免与大量DOM对象绑定到点击事件相关的内存或性能问题的最佳做法 [英] Best practice to avoid memory or performance issues related to binding a large number of DOM objects to a click event

查看:116
本文介绍了避免与大量DOM对象绑定到点击事件相关的内存或性能问题的最佳做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我正在使用Chrome开发工具测试各种方法,但是我不认为自己在现代浏览器中是JS的专家,所以我正在寻找额外的反馈来补充我的测试。



我有一个页面,定期有600多个元素需要处理点击事件。我可以想到至少有3种不同的方式来处理这个问题,但我正在考虑页面大小,速度,JS内存问题,对象计数相关问题(在性能和稳定性方面)。


  1. Include onClick =foo(this);对于每个元素,并在我的一个包含的.js文件中定义函数。 - 更大的页面,功能定义一次,我会想到一个更小的内存占用的JS,但更大的页面作为一个整体。

  2. 使用jQuery和$(selector).click( FOO(本)); - 更小的页面,功能定义一次,我会想到一个更大的内存占用的JS,但较小的页面整体。

  3. 使用jQuery和$(selector).click(function(this){ }); - 最小的页面,功能定义一次,但我希望这是记忆中最苛刻的(我担心我可能会碰到一些晦涩的问题与jQuery或JS作为一个整体),但在概念上最优雅。 >

我必须支持每个浏览器可能会期望jQuery运行。项目数量可能会增加更多(可能是4倍或5)。



如果还有另一种方法会更好,我很乐意听到。如果有人想要告诉我我的3种方法的任何优点/缺陷,我也真的很感激。

解决方案

将大量类似元素绑定到单个事件的最有效方式是利用事件冒泡。您将单个事件处理程序附加到公共父对象,然后在单个事件处理程序中,检查事件发生的对象,以查看原始对象是否正在监视此事件的对象。



为了附加事件,它只需要一个事件处理程序,您可以从该一个事件处理程序中提供无限数量的子对象。



每个事件的运行时都会出现轻微的性能下降(可能不明显),因为事件必须在事件处理程序看到之前冒泡到父级,并且事件处理程序必须检查源对象是否为期望的目标对象。但是,安装一个单独的事件处理程序而不是安装数千个单独的事件处理程序是非常有效的。



委托事件处理的优点是它可以动态地工作创建对象,甚至在安装事件处理程序后创建的对象 - 对直接安装在对象本身(非委派事件处理程序)上的事件处理程序来说,这并不奏效。



在jQuery中,您可以使用这样的委托事件处理:

  $(常用父选择器).on('click ',目标对象的选择器,function(){}); 

例如,HTML:

 < div id =parent> 
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< button class =addButton>添加< / button>
< / div>

代码:

 code> $(#parent)。on('click','.addButton,function(e){
//将`this`的值设置为发起事件的对象
//例如点击
});


First of all, I am testing various approaches using Chrome Dev Tools but I don't consider myself 'expert' with JS in todays modern browsers so I'm looking for additional feedback to compliment my testing.

I have a page which will regularly have 600+ elements that need to handle click events. I can think of at least 3 fairly different ways to approach this but I'm thinking about page size, speed, JS memory issues, object count-related issues (in terms of both performance and stability).

  1. Include onClick="foo(this);" for each of the elements and define the function in one of my included .js files. -- Larger page, function defined once, I would think a smaller memory footprint for the JS, but larger for the page as a whole.
  2. Use jQuery and $(selector).click(foo(this)); - Smaller page, function defined once, I'd think a larger memory footprint for the JS but smaller page overall.
  3. Use jQuery and $(selector).click(function(this) { }); - Smallest page, function defined once, but I expect this to be the most demanding in terms of memory (and I'm concerned I might hit some obscure issue with jQuery or JS as a whole) but conceptually the most elegant.

I must support just about every browser one might expect jQuery to run in. The number of items could increase even more (possibly by a factor of 4 or 5).

If there's another approach that would be better, I'd love to hear it. If anyone wants to educate me on any advantages/pitfalls of my 3 approaches, I'd really appreciate that too.

解决方案

The most efficient way to bind a large number of similar elements to a single event is to make use of event bubbling. You attach a single event handler to a common parent object and then, in the single event handler, you examine which object the event originated in to see if the original object is an object you're monitoring for this event.

For attaching the event, it costs you only a single event handler and you can serve an infinite number of child objects from that one event handler.

There's a slight performance degradation at the run-time of each event (probably not noticeable) because the event has to bubble up to a parent before the event handler sees it and the event handler has to check if the source object is a desired target object or not. But, it's massively more efficient to install the one single event handler rather than installing thousands of individual event handlers.

Delegated event handling also has the advantage that it works well for dynamically created objects, even objects created after the event handler was installed - something that doesn't not work well for event handlers installed directly on the objects themselves (non-delegated event handlers).

In jQuery, you can use delegated event handling like this:

$(common parent selector).on('click', selector of target objects, function() {});

For example, HTML:

<div id="parent">
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
    <button class="addButton">Add</button>
</div>

Code:

$("#parent").on('click', ".addButton", function(e) {
    // the value of `this` is set to the object that originated the event
    //     e.g. what was clicked on
});

这篇关于避免与大量DOM对象绑定到点击事件相关的内存或性能问题的最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆