最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Best practice to avoid memory or performance issues related to binding a large number of DOM objects to a click eve

programmeradmin1浏览0评论

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 pliment 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.

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 pliment 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.

Share Improve this question asked Mar 24, 2013 at 2:55 rainabbarainabba 4,2871 gold badge41 silver badges38 bronze badges 4
  • Is it a single function for all items, or different functions? I so, I suggest delegation, as the two current answers do. – bfavaretto Commented Mar 24, 2013 at 3:01
  • Three simple rules; delegate, delegate, delegate. – Beetroot-Beetroot Commented Mar 24, 2013 at 3:03
  • Why do you think your option (3) would be more demanding than (2) for memory? (And as an aside, note that both (2) and (3) are slightly wrong as far as the function parameters, though that's easily fixed.) – nnnnnn Commented Mar 24, 2013 at 3:05
  • nnnnnn: My thought was that the function is being declared multiple times and each instance of the function would require its own memory (assuming the interpreter isn't optimizing it by removing the duplicate but declarations). – rainabba Commented Mar 26, 2013 at 22:36
Add a ment  | 

4 Answers 4

Reset to default 8

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 mon 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:

$(mon 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
});

Look at the delegated version of the "on" event handler, described here http://api.jquery./on/

In the section titled "Direct and Delegated events"

You should use jQuery's on() method for this. On allows you to attach a handler to a high level DOM node (such as document) and rely on event bubbling to execute a handler when the event is triggered.

$(document).on('click', [selector], [data], handler);

You could do something simple like this in native js.

<div id="test">
    <input type="button" value="Button 1"/>
    <input type="button" value="Button 2"/>
    <input type="button" value="Button 3"/>
</div>
<script>
    var parent = document.getElementById('test');
    parent.onclick = function(e){
        alert(e.target.value);
    };
</script>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论