When binding event to multiple elements at once, new instance for each element?
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:
- Don't think so, not sure of the syntax however.
- 1 as I explained
- 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.
精彩评论