jQuery chaining - Can I write cleaner code?
i'm slowly getting my head around jQuery and learning more each day, however I wonder if I can create cleaner code. I have heard of 'chaining' but am not sure how I apply this.
Below is a piece of working jQuery i've written, but although it works, can I reduce it/make it cleaner by chaining any of it?
The script removes a class on button click and adds another class whilst simultaneously hiding another div. At the end I have added on keydown events to use as well as button presses.
<script type="text/javascript">
$('button').click(function(e) {
if ($(this).hasClass('grid')) {
$('#primar开发者_运维技巧y ul').removeClass('stylelist').addClass('grid');
$('#primary ul .single-style-text').hide();
}
else if($(this).hasClass('list')) {
$('#primary ul').removeClass('grid').addClass('stylelist');
$('#primary ul .single-style-text').show();
}
});
$(document).bind('keydown', function(e) {
if (e.which == 71) {
$('#primary ul').removeClass('stylelist').addClass('grid');
$('#primary ul .single-style-text').hide();
}
});
$(document).bind('keydown', function(e) {
if (e.which == 76) {
$('#primary ul').removeClass('grid').addClass('stylelist');
$('#primary ul .single-style-text').show();
}
});
</script>
There's one thing you can further chain in there:
$('#primary ul')
.removeClass('stylelist').addClass('grid')
.find('.single-style-text').hide();
But the one thing that would make your code better would be to move that functionality into a function (even though this removes a little chaining):
function switchView(view) {
var ul=$('#primary ul');
ul.removeClass('stylelist').removeClass('grid');
ul.addClass(view);
var singleStyleText=ul.find('.single-style-text');
singleStyleText.hide();
if(view=='stylelist') {
singleStyleText.show();
}
}
Then your event handlers could look like this:
$('button').click(function() {
if($('#primary ul').hasClass('grid')) {
switchView('stylelist');
}else{
switchView('grid');
}
return false;
});
$(document).bind('keydown', function(e) {
if(e.which == 71) {
switchView('grid');
}else if(e.which == 76) {
switchView('stylelist');
}
});
$('button').click(function(e) {
var ul = $('#primary ul');
if ($(this).hasClass('grid')) {
ul.removeClass('stylelist').addClass('grid').find('.single-style-text').hide();
} else if($(this).hasClass('list')) {
ul.removeClass('grid').addClass('stylelist').find('.single-style-text').show();
}
});
$(document).bind('keydown', function(e) {
var ul = $('#primary ul');
if (e.which == 71) {
ul.removeClass('stylelist').addClass('grid').find('.single-style-text').hide();
} else if (e.which == 76) {
$('#primary ul').removeClass('grid').addClass('stylelist').find('.single-style-text').show();
}
});
but if its just a list or a grid you want to toggle you can write it on two lines of code. (per event), like:
$('button').click(function(e) {
var isGrid = $(this).hasClass('grid');
$('#primary ul').removeClass(isGrid ? 'stylelist' : 'grid').addClass(isGrid ? 'grid' : 'list').find('.single-style-text')[isGrid ? 'hide' : 'show']();
});
A few cleanups...
To start, we can combine these two keydown events. There's really no need to have multiple calls, since what you're dealing with is a value from the event.
<script type="text/javascript">
$('button').click(function(e) {
if($(this).hasClass('grid')) {
$('#primary ul').removeClass('stylelist').addClass('grid');
$('#primary ul .single-style-text').hide();
}
else if($(this).hasClass('list')) {
$('#primary ul').removeClass('grid').addClass('stylelist');
$('#primary ul .single-style-text').show();
}
});
$(document).bind('keydown', function(e) {
if (e.which == 71) {
$('#primary ul').removeClass('stylelist').addClass('grid');
$('#primary ul .single-style-text').hide();
}
if (e.which == 76) {
$('#primary ul').removeClass('grid').addClass('stylelist');
$('#primary ul .single-style-text').show();
}
});
</script>
Now, you're doing a lot of repetitive work... How about minimizing that by wrapping that up in a function?
Now, I may have gotten a bit carried away...
<script type="text/javascript">
$('button').click( swapClasses() );
$(document).bind('keydown', function(e) {
if (e.which == 71) {
$('#primary ul').removeClass('stylelist').addClass('grid');
$('#primary ul .single-style-text').hide();
}
else if (e.which == 76) {
$('#primary ul').removeClass('grid').addClass('stylelist');
$('#primary ul .single-style-text').show();
}
});
swapClasses = function() {
$('#primary ul').toggleClass( 'stylelist' ).toggleClass( 'grid' );
$('#primary ul .single-style-text').toggle( showOrHide );
}
</script>
Looks a wee bit cleaner...
As far as chaining goes, i don't think there's much to change around. A few things that i would change though...
Where is your document.ready ?
Cache your selectors so they can be reused.
Use more specific selectors. Instead of just button specify the class too.
<script type="text/javascript"> $(function(){ var primary = $('#primary ul'); var single_style_text = primary.find('.single-style-text'); $('button.grid','button.list').click(function(e) { if ( $(this).hasClass('grid') ) { primary.removeClass('stylelist').addClass('grid'); single_style_text.hide(); } else if( $(this).hasClass('list') ) { primary.removeClass('grid').addClass('stylelist'); single_style_text.show(); } }); $(document).bind('keydown', function(e) { if (e.which == 76) { primary.removeClass('grid').addClass('stylelist'); single_style_text.show(); } if (e.which == 71) { primary.removeClass('stylelist').addClass('grid'); single_style_text.hide(); } }); }) </script>
精彩评论