jQuery custom selectors with parameters

My last tutorial on how to create a custom jQuery selector showed you the basics of creating custom filters in jQuery. Now, it is time to get more serious with selectors and create more advanced jQuery selectors – custom jQuery selectors with parameters. To get an idea of what I am talking about think of :contains(someText) selector.

Anyway, let’s create our own jQuery selector that takes arguments. The basic syntax is the same:

$.expr[':'].test = function(obj, index, meta, stack){
    /* obj - is a current DOM element
       index - the current loop index in stack
       meta - meta data about your selector !!!
       stack - stack of all elements to loop
   
       Return true to include current element
       Return false to explude current element
    */
};

meta is a parameter we are interested in. meta is an array that carries an information about our selector. Here is what it looks like:

$('a:test(argument)');
//meta would carry the following info:
[
    ':test(argument)', // full selector
    'test',            // only selector
    '',                // quotes used
    'argument'         // parameters
]

$('a:test("arg1, arg2")');
//meta would carry the following info:
[
    ':test('arg1, arg2')', // full selector
    'test',                // only selector
    '"',                   // quotes used
    'arg1, arg2'           // parameters
]

Here as you can see, we can make use of the arrays fourth (meta[3]) value to get a hang of our parameters.

Creating custom jQuery selector with parameters

Now, let’s improve our selector from previous post that selects all links with non empty rel attribute and make it select any element with specified non empty attribute. Here is the code to do just that:

$.expr[':'].withAttr = function(obj, index, meta, stack){
  return ($(obj).attr(meta[3]) != '');
};

See it in action here.

Find & select all external links with jQuery

Selecting all external links and amending them in some way is probably one of the most used jQuery tutorials. By selecting all anchor links on the page and for example adding a CSS class with only one jQuery line shows how jQuery is simple and powerful. Also if you are progressively enhancing your website this is one of the trick you might use.

Actually, I had to select all external links and add an image that indicates it the other day. So, I created a custom jQuery selector called :external that makes finding external links easier for you. (Read “Custom jQuery Selectors” post to learn how to create your own custom selectors)

External links custom jQuery selector code:

// Creating custom :external selector
$.expr[':'].external = function(obj){
    return !obj.href.match(/^mailto\:/)
            && (obj.hostname != location.hostname);
};

// Add 'external' CSS class to all external links
$('a:external').addClass('external');

You can see this code in action here.

You may use the code above to:

  • Add CSS class to all external links
  • Dynamically add an image after the link to indicate that it is an external link
  • Bind a click event to track what links where clicked
  • etc.

Update: The return part was update to take into the account the mailto links as suggested in comments by Phillipp and Karl below.

Custom jQuery selectors

jQuery makes it easy to select elements you need using CSS selectors. It is undoubtedly one of the jQuery features that makes it a great javascript library. On top of standard CSS selectors jQuery introduces some custom selectors that makes your code even more simpler and easier to read.

Examples of custom jQuery selectors are: :header, :even, :odd, :animated, :contains(text), etc.

And the best part is that jQuery lets you create and define your own custom selectors using custom selector creation template below.

jQuery Custom Selector Creation Template:

$.expr[':'].test = function(obj, index, meta, stack){
    // obj - is a current DOM element
    // index - the current loop index in stack
    // meta - meta data about your selector
    // stack - stack of all elements to loop
   
    // Return true to include current element
    // Return false to explude current element
};

// Usage:
$('.someClasses:test').doSomething();

Let’s now create a very simple custom selector using the template above. Let’s say we want a custom jQuery selector that will return elements with nonempty rel attribute.

$.expr[':'].withRel = function(obj){
  var $this = $(obj);
  return ($this.attr('rel') != '');
};

// Usage:
$('a:withRel').css('background-color', 'yellow');

The code above creates a custom selector that will select only elements with not empty rel attributes. Here is the above code’s demo page.

You might also be interested in reading about jQuery custom functions.

UPDATE: Read about creating custom jQuery selectors with parameters.

Mozilla Jetpack & jQuery

Jetpack is a new product of Mozilla Labs. It is basically a new way to create Firefox plugins using web programming languages like HTML, CSS and JavaScript. The idea behind is the same as for Adobe AIR. If you know HTML, CSS and JavaScript you can build a Firefox plugin in no time.

The bad news is that Jetpack is still in early developer testing stage, so it is not available in Firefox yet. The good news is that Jetpack is using jQuery and you can use it to do all kinds of stuff like responding to user click events, manipulate any website DOM elements and use cross-site XMLHttpRequest object, etc. Besides, Jetpack can be setted up to use other javascript libraries such as prototype.js, dojo.js etc. and third party API libraries such as Twitter, Google, etc. API libraries.

Where to go from here?

If you want to learn more about Jetpack and how to use jQuery with it refer to this links:

  1. Watch this Jetpack video
    Good starting point to get an idea of what Jetpack is and how jQuery is used within it. Also good starting point to understand what kind of things can be don with Jetpack.
  2. Read Jetpack tutorial
    Official Jetpack introduction tutorial from Jetpack team. Probably the first article you must read about developing for Jetpack.
  3. Jetpack API documentation
    A list of global variables that are available in your Jetpacks. Currently it has a very limited global variables and functions.
  4. Jetpack plugin for your Firefox
    If you want to develop Jetpacks you need to install this Firefox plugin.
  5. Available Jetpack to investigate the code here and here.
    Most developers prefer understanding the logic and learning by investigating someone else’s code easier.

I am planning to post more Jetpack tutorials on this blog and try to show what kind of things can be done using Jetpack and jQuery. Keep tuned by following me on Twitter (@jQueryHowto) or subscribe to blog’s RSS.

jQuery Beginner tutorials

This post is about a decision I made yesterday to post more jQuery beginner tutorials on the blog.

See a list of all jQuery beginner tutorials on this blog.

There were two reasons for me making this decision:

  1. People are finding this jQuery blog searching for jQuery basics
    Analyzing my Google Analytics account I found that a lot of developers who are landing on this blog through search are jQuery Beginners and looking for basic jQuery method explanations. So publishing more beginner tutorials would benefit them. They would get more relevant information from the new Beginner category posts.
  2. I am being asked more and more jQuery Beginner questions
    I have been quite active on Twitter (@jQueryHowto) and other online discussion boards lately answering and helping developers with their jQuery problems. The jQuery community on twitter is quite active and most of the jQuery problems I came across were jQuery beginners questions. I could not squeeze my ideas or explanations of jQuery basics in 140 characters, so I had to search the web for explanation and post a link to the website.

Message to non beginner readers:

I hope I will not lose intermediate and advanced jQuery developers with this posts. I enjoy your insights and comments on my posts and actually learn a lot more from your feedback. I will try to post no more than one beginner tutorial or insight per my regular post. I hope for your understanding.

List of jQuery Beginner Tutorials and posts:

I actually posted several jQuery Beginner tutorials and method explanations on this blog with backdate. I will try to keep this post updated with the links for my beginner posts so you can bookmark this page or share it with your jQuery beginner colleagues.

See all jQuery beginner tutorials on this blog.
  1. Using $.noConflict()
  2. How to check if checkbox is checked
  3. Identify how many elements were selected
  4. Adding custom functions to jQuery
  5. Identifying & locating mouse position in jQuery
  6. How to load jQuery from Google CDN servers
  7. Setting HTML tag’s attribute in jQuery
  8. Getting HTML tag’s attribute in jQuery
  9. Binding jQuery events to AJAX loaded elements
  10. How to disable and enable an element
  11. Quick tip to solve a problem with setting CSS background image to an element

Javascript for() loop vs jQuery .each() performance comparison

This post is an outcome of 15 minutes of free time and a question that I had yesterday. This question were:

  1. How fast jQuery’s .each() method is?
  2. How does it compare to javascript’s native for loop?

It is clear without any performance tests that native javascript for loop is faster, but I always used jQuery’s .each() utility with caution. It always felt like I will get a performance penalty for using it. So I tried to never use it.

So today, I wrote up a little javascript performance test and got my answers. Basically, I created an array and iterated through it using native for loop and jQuery’s .each() iterator. All I did was just an iteration and no array amendments or any other logic. I know it is very basic, but that’s exactly what I want to know. How fast they iterate!

Performance test code:

console.time('TestNative');
length = myArray.length;
for( i=0; i < length; i++){
  myArray[i];
}
console.timeEnd('TestNative');

console.time('TestjQuery');
jQuery.each(myArray, function(i, val) {
  val;
});
console.timeEnd('TestjQuery');

Performance test results:

JavaScript Native FOR loop

Array size    Time
==========    ======
10,000        7ms
100,000       62ms
1,000,000     613ms


jQuery .each() loop

Array size    Time
==========    ======
10,000        10ms
100,000       177ms
1,000,000     1100ms

As you can see native for loop is never over 1ms. That’s probably because we are not doing anything with our array and browser simply optimizes the code or maybe its that fast :)

Usually we don’t have more than 1000 items in our arrays and objects, that is why I guess it can be concluded that using .each() loop in our code will not cause any performance penalties.