jQuery - Page with a ton of checkboxes, how to bind?
I have a page of checkboxes, in some cases more than 100. I'm currently doing this:
$('form[name=myForm] input[name=myCheckbox]').change(function(){
var numChkd = $('input[name=myCheckbox]:checked').size();
console.log(numChkd);
};
But as you could imagine this can get wicked slow. Is there a better way to bind an event to multiple elements? This works, but I want to know 开发者_如何学编程if there is a better way?
You can bind an event to the parent container that will wrap all of the checkboxes and then check if the object that caused an event is a checkbox. This way you only bind one event handler. In jQuery you can use $.live event for this.
Don't recount every time a checkbox changes. Just use a global variable, like this:
var CheckboxesTicked = 0;
$(document).ready(function() {
CheckboxesTicked = $(":checkbox:checked").length;
$(":checkbox").change(function() {
if ($(this).is(":checked")) {
CheckboxesTicked += 1
} else {
CheckboxesTicked -= 1
}
});
});
Btw, the documentation states that you'd better use .length instead of .size() performance wise.
You could create a container element (like a Div with no styling) and attach the event handler to the container. That way, when the change()
event happens on one of the checkboxes and percolates up the DOM, you'll catch it at the container level. That's one way to make this faster.
You should use .delegate()
. One binding on a parent element can replace all the individual bindings on the child elements. It's perfect for this situation (and also solves the problem of attaching behavior to dynamically-added elements, should the need arise).
$('form[name=myForm]').delegate('input[name=myCheckbox]','change', function(){
var numChkd = $(this).siblings(':checked').length; // assuming siblings
console.log(numChkd);
});
This is how I would approach it:
$('form[name=myForm]').each(function() {
var $form = $(this),
$boxes = $form.find('input[name=myCheckbox]');
$form.delegate('input[name=myCheckbox]', 'change', function() {
var numChkd = $boxes.filter(':checked').length;
console.log(numChkd);
});
});
This takes advantage of caching the $boxes
selection. It will look for all the boxes when it sets up the event. It uses .delegate()
to attach an event to the form
which will get fired anytime an child input[name=myCheckbox]
creates a change
event. In this event handler, you can easily filter the already obtained list of checkboxes by which ones are :checked
and get the length
of the matched elements. (The documentation for .size()
basically states there is no reason to ever use it... It just returns this.length
anyway...)
See this fiddle for a working demo
demo: http://jsfiddle.net/kKUdm/
$(':checkbox').change(function(){
if($(this).is(':checked')){
var name = $(this).attr('name');
var value = $(this).val();
console.log(name + ':' + value);
}
});
Var $chks = $(":checkbox");
Var ChkCount =0;
Var chktimer =0;
Function updateChkCount(){
ChkCount = $chks.filter(":checked").length;
$chks.end();
// do something witb ChkCount
}
$chks.bind("check change", function(){
clearInterval(chktimer);
chktimer = setInterval("updateChkCount()",250);
});
精彩评论