4 Useful jQuery selectors

I’ve created quite a few jQuery components before, and I continue to do so every day. This forces me to find best practices and short-cuts to cut down development time, keep things simple and cross browser compatible.
This article is going to be about a bunch of jQuery selectors that I find useful and use on a daily basis because, they simply work well for me.

One of my favourite things about CSS are the selectors. I get an extremely warm and tingly feeling when I can make an amazing website with a very small and compact CSS file. Using the correct selector when it is appropriate can cut your CSS file size in half.

At the moment, we can’t use CSS3 selectors or properties guilt free yet (For obvious reasons). This is where jQuery selectors come in and save the day.

Not only does jQuery allow you to use most CSS3 selectors, but there are a bunch of extra very awesome and unique jQuery selectors.

:animated

:animated selects all elements that are currently being animated.
This might not sound too useful, but it really is.

I use it almost every time I use an animation on hover with jQuery. Consider the following:

$('#nav li a').hover(function(){
	$(this).fadeTo(300, 1);
}, function(){
	$(this).fadeTo(300, 0.5);
});

On hover, that will cause each #nav li a to fade in completely on hover, and fade to 50% opacity on mouse-exit. If you quickly hover your mouse – on and off, on and off – multiple times, it will cause the animations to queue up. This is almost never an ideal situation. We want the animation to run once, something must be done about it!

Chris Coyier has an interesting article about this and as he mentions, Ralf Stoltze seems to have the best solution.

The quick solution I generally use is as follows:

$('#nav li a').hover(function(){
	// If this is not animated
	if(!$(this).is(':animated')){
		$(this).fadeTo(300, 1);
	}
}, function(){
	$(this).fadeTo(300, 0.5);
});

I find :animated most useful when it comes to excluding animated elements.

:contains

This selector selects an element that contains specific text.

I’ve used this selector quite a few times in very similar situations. I generally use it to select specific <li>s in a navigation menu. This is normally useful when there is limited HTML control, such as within certain CMSs.

WordPress 3 has a new feature which allows users to add items to the navigation menu and easily move them around, this is a prefect situation for this jQuery selector.

Consider the html:

<ul>
	<li><a href="index.php">Home</a></li>
	<li><a href="about.php">About</a></li>
	<li><a href="contact.php">Contact</a></li>
</ul>

Let’s say we want to add a class of .contact to the <li> that contains the text ‘Contact’ in order to add a custom background.
We could use CSS3 but that isn’t supported in IE6-8.
We could select the third item in the list or the last item using jQuery. This would work perfectly, but if the user changes the position of the list items, the wrong item will have the class of contact.

I’ve found that the easiest way to deal with this is to use the jQuery selector :contains.
All we need to is:

$('ul li:contains("Contact")').addClass('contact');

This will select Contact no matter where it is situated.

Note: This will select anything containing contact, even ‘Mr Contact’ or ‘Contact Me’.

:visible / :hidden

These jQuery selectors, are opposite, yet very similar.
:visible selects all visible elements and :hidden selects all hidden elements.

I’ve found myself selecting elements that are not visible instead of looking for elements that are hidden.

$('li').not(':visible')
!$('li:visible')
$('li:hidden')

Each of those do the same thing, but as you can see, the third example is the most simple and semantic.

I use :visible very often. It is extremely easy, efficient and useful when creating an image viewer or something that only has one visible element at a time.

:has()

Lastly we have the :has jQuery selector. I find it extremely useful when fixing up other people’s work for some reason.

Borders are often used to style links in place of text-decoration: underline. Often it looks slightly more stylish. I’m currently using this border-method on css-plus.com.
Unfortunately, this is a pretty common problem:

a{border-bottom: 2px solid #000;}
a:hover{border-bottom: 2px solid #000;}
<a href="#">Link</a>
<a href="#"><img src="images/image.jpg" alt="" /></a>

This method creates a border underneath the image because it is wrapped within an anchor link.
:has can be used to solve this problem.

$('a:has("img")').addClass('image-link');
a.image-link{border: none;}
a.image-link:hover{border: none;}

:has is extremely useful, but since it requires javascript, I wouldn’t base a websites styling on too much jquery :has. Unfortunately, this will probably never be supported within CSS. Jonathan Snook has written a very interesting article regarding this topic.

Conclusion

jQuery offers some very awesome selectors, some of which might be available via CSS one day. However, as much as I feel like I am free to use them within a javascript component, I feel I am prevented from using them to help me create a layout because there are still people who have javascript disabled – for whatever reason – and the website should still look presentable without javascript.

What say you?

  1. Muhammad Hassaan says:

    interesting post