开发者

When binding event to multiple elements at once, new instance for each element?

开发者 https://www.devze.com 2023-04-10 18:42 出处:网络
I have 100 BUTTONS in my page ( each of them has class=\'btn\'). Also I have a singlebutton which prepare all the other100 buttons.

I have 100 BUTTONS in my page ( each of them has class='btn').

Also I have a single button which prepare all the other 100 buttons.

<input type=开发者_运维知识库'button' onclick='bindTheClickevent()' />

When pressed, - it calls bindTheClickevent() - (which binds the click event to all 100 others).

In the Script Section I put:

function bindTheClickevent ()
{
        $(".btn").bind('click',function () {
          $(this).css('color','red');
         });
}

Questions

1) In memory, how many instances of the anonymous function are created?

2) In memory, Does the bindTheClickevent() function will ever be free (GC)? - please notice that the Bind is called inside the bindTheClickevent function...

3) When, eventually - the bindTheClickevent function will be free to GC ?

Lets make a change

function bindTheClickevent ()
    {
            $(".btn").bind('click',function () {
              changeColor($(this));
             });
    }

function changeColor(obj)
{
 $(obj).css('color','red');
}

Now - after the change

1) Is there any difference if I Do that?

2) In memory, how many instances of the anonymous function are created?

3) Does the bindTheClickevent() function will ever be free (GC) ? - please notice that the Bind is called inside the bindTheClickevent function...


"1) In memory , how many instances of the anonymous function are created ?"

Which anonymous function?

For the inline onclick, you get a function assigned to the onclick property of the element like this:

function(event) {

    bindTheClickevent();

}

... or similar depending on the implementation. That function will be free for GC when the element is dereferenced or the function is dereferenced from the onclick property.

With respect to the jQuery code:

$(".btn").bind('click',function () {
    $(this).css('color','red');
});

...while the anonymous function is shared, what you don't see is that if the elements in question do not already have a jQuery handler bound, jQuery will internally create a unique function for each element.

That internal handler is what actually gets bound to the element, and when the element receives an event, that handler is invoked, analyzes the event, and invokes the handler you originally passed (if necessary).

This means 100 jQuery bound elements equals 101 unique function instances.

In order to make sure that any handlers bound using jQuery are GC'd, you need to make sure that you always use jQuery to remove DOM elements. If you don't, all the data (including handlers) stored in jQuery.cache doesn't get cleaned up, and so they'll always be referenced via the global jQuery namespace.


EDIT:

Given that there are 100 elements that have the class btn, that don't have any handlers bound by jQuery, then this code:

$(".btn").bind('click',function () {
    $(this).css('color','red');
});

...will create 101 unique Function instances.

Why 101?

Well, what jQuery does is the first time you bind a handler to an element, it internally creates a unique generic handler for every element. This is the handler that is actually invoked when an event occurs, and handles all event types.

Your handler function is never actually bound to the element.

So that generic internal handler when invoked will analyze the event that took place, and see if any handlers have been associated with the given element using .bind() that match that event type. If so, it calls the handler that passed.

Now let's say you bind another handler:

$(".btn").bind('mouseenter',function () {
    $(this).css('color','blue');
});

...since we're binding to the same elements, they already have the necessary internal handler and another does not need to be created. So all that happens is that the function you pass is referenced internally, and is invoked by the generic internal handler when needed.

As such, given the code snippets above, there now exists 102 unique Function instances.


It looks like only one instance of the function is created in both circumstances. It appears as though References to the anonymous function are attached as the event handlers for each element.

Example - Using a closure to show the sharing of scope between button event handlers.

Note that this can cause interesting behavior if you involve closures because all elements will share the same function (and closure scope).

And no, your declared functions will not be GC'd because of their global scope.

Additionally

To attach them independently (not by reference), loop over the selected elements with .each() and attach the function individually.

Example

$('.btn').each(function() {
    $(this).bind('click',function() {
        // each '.btn' has it's own copy of
        // this anonymous function
    }
});


If you do something like these:

for (someiterations)
{
    $(myobj).bind("click",function()
    {
        // ...bla...
    });
}

In this case you are creating a new function each iteration. In your function this is not happening because you are passing the function to a parameter, so there is a place which has stored it's reference (yea the function param) that will do something like this:

for (iterations)
{
    myob.addEventHandler(event, funcref);
}

So should be ok, now:

  1. Don't think so, not sure of the syntax however.
  2. 1 as I explained
  3. No because it's in the global scope and it's not assigned to an instance, you can think of it as a constant, not as a variable

Note: The anonymous function will not be released, it's referenced by the event handler.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号