jQuery: Is it possible to group several events into a single .click()?
I have the following code which processes a click from a tab and loads contents via ajax:
$(document).ready(function()
{
$("#tab1").click(function()
{
loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
});
$("#tab2").click(function()
{
loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
});
$("#tab3").click(function()
{
loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
});
$("#tab4").click(function()
{
开发者_JAVA百科 loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
});
});
You'll notice that there are lots of repeated code.
Is there any way of grouping the #tab1, #tab2, .... into a single .click(function() ?
$(document).ready(function()
{
$("#tab1, #tab2, #tab3, #tab4").click(function()
{
loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
});
});
edit to add some value to the answer (see also other answers, which already mention some, maybe even all, of the following):
you should give the tabs a common identifier, such as a css class: abstraction is good, mmkay?
$(document).ready(function() { $(".tab").click(function() { loadTab($(this).attr("href") + "?ajax=1"); return false; }); });
the tabs are likely to have a common ancestor not too far above. like, they're all (inside) <li>'s within a single <ul>. explore that and use event delegation.
$(document).ready(function() { $("#tabs").click(function(e) { if (!$(e.target).is('.tab')) return; loadTab($(this).attr("href") + "?ajax=1"); return false; }); });
use the
delegate
API added in 1.4.2 to spare the guard clause:$(document).ready(function() { $("#tabs").delegate('.tab', 'click', function() { loadTab($(this).attr("href") + "?ajax=1"); return false; }); });
no need to get overzealous with jquery application:
$(document).ready(function() { $("#tabs").delegate('.tab', 'click', function() { loadTab(this.href + "?ajax=1"); return false; }); });
Or, give all the tab
item the same CSS class and then do
$(".classname").click(...);
In this way, even if you add new tabs your code will still automagically work :)
I would suggest the following alternatives:
- live: give your tabs a certain css class and select on that: $('.tabClass').live('click', function() {// dosomethinguseful});
The reason to go for live instead of click could be that there could be made extra tabs on the fly. Live handles this for you automatically. - Make use of jQueryUI tabs control. Easy to use and it has ajax capability baked in.
As an alternative you can delegate a single click event to do different things depending on the target of the click (known as event delegation)
Markup:
<div id="tabs">
<a href="#1">Tab 1</a>
<a href="#2">Tab 2</a>
<a href="#3">Tab 3</a>
<a href="#4">Tab 4</a>
</div>
JavaScript:
$("#tabs").click(function(e)
{
e.preventDefault();
var target = $(e.target);
if(target.is("a")) {
alert(target.attr("href") + "?ajax=1");
}
});
There is a shortcut function to do this in jQuery called .delegate(), a bit redundant imo, but worth checking out.
You can use multiple selectors in jQuery by comma-delimiting, as another answer has already pointed out. However, I wanted to point out another way to share code that, although it does not really apply in this particular case, it is good knowledge to have. Say you had multiple events that needed the use the same function. A cool thing about Javascript is that functions can be stored as a variable and then re-used...
var func = function(e) {
loadTab($(this).attr("href") + "?ajax=1");
e.preventDefault(); // proper way to cancel the event
return false; // cancel the event
}
$("#tab1,#tab2,#tab3,#tab4").click(func);
Like I said, it doesn't have any benefits in this particular case, but there are times that you need to use the same function for multiple events.
if you give all the tabs a class, say ".tabs" you could do this:
$(".tabs").each(function(){
$(this).bind('click', function(){
loadTab($(this).attr("href") + "?ajax=1");
return false; // cancel the event
})
});
no sure i'ts the most optimized way to go, but it should work.
精彩评论