Utility Methods

Contact Us or call 1-877-932-8228
Utility Methods

Utility Methods

jQuery offers several utility methods in the $ namespace. These methods are helpful for accomplishing routine programming tasks. Below are examples of a few of the utility methods; for a complete reference on jQuery utility methods, visit http://api.jquery.com/category/utilities/.

$.trim - removes leading and trailing whitespace

$.trim(' lots of extra whitespace ');
// returns 'lots of extra whitespace'

$.each - iterates over arrays and objects.

$.each([ 'foo', 'bar', 'baz' ], function(idx, val) {
	console.log('element ' + idx + 'is ' + val);
});

$.each({ foo : 'bar', baz : 'bim' }, function(k, v) {
	console.log(k + ' : ' + v);
});

Remember that there is also a method $.fn.each, which is used for iterating over a selection of elements.

$.inArray - returns a value's index in an array, or -1 if the value is not in the array.

var myArray = [ 1, 2, 3, 5 ];

if ($.inArray(4, myArray) !== -1) {
	console.log('found it!');
}

$.extend - changes the properties of the first object using the properties of subsequent objects.

var firstObject = { a : 1, foo : 'bar' };
var secondObject = { b : 2, foo : 'baz' };

var newObject = $.extend(firstObject, secondObject);
// The structure of firstObject will now be:
// { a : 1, b : 2, foo : 'baz' }

If you don't want to change any of the objects you pass to $.extend, pass an empty object as the first argument.

var firstObject = { a : 1, foo : 'bar' };
var secondObject = { b : 2, foo : 'baz' };

var newObject = $.extend({}, firstObject, secondObject);
// The structure of firstObject will now be unchanged:
// { a : 1, foo : 'bar' }
// The structure of newObject will now be:
// { a : 1, b : 2, foo : 'baz' }

$.proxy - returns a function that will always run in the provided scope, that is, sets the meaning of this inside the passed function to the second argument.

There are two forms of this method. The first takes two parameters, a function reference and a scope variable. The second takes an object and a string with the name of the method within that object. In this form, the meaning of this in the second parameter is locked to the first parameter object.

var myFunction = function() { console.log(this); };
var myObject = { foo : 'bar' };

myFunction(); // logs window object

var myProxyFunction = $.proxy(myFunction, myObject);
myProxyFunction(); // logs myObject object

// If you have an object with methods, you can pass the object
// and the name of a method to return a function that will
// always run in the scope of the object.
var myObject = {
	myFn : function() {
		console.log(this);
	}
};

$('#foo').click(myObject.myFn); // logs DOM element #foo
$('#foo').click($.proxy(myObject, 'myFn')); // logs myObject

Checking Types

As mentioned in the "JavaScript Basics" section, jQuery offers a few basic utility methods for determining the type of a specific value.

Checking the Type of an Arbitrary Value

var myValue = [1, 2, 3];

// Using JavaScript's typeof operator to test for primitive types
typeof myValue == 'string';    // false
typeof myValue == 'number';    // false
typeof myValue == 'undefined'; // false
typeof myValue == 'boolean';   // false

// Using strict equality operator to check for null
myValue === null; // false

// Using jQuery's methods to check for non-primitive types
jQuery.isFunction(myValue);    // false
jQuery.isPlainObject(myValue); // false
jQuery.isArray(myValue);       // true

Storing and Retrieving Data Related to an Element

As your work with jQuery progresses, you'll find that there's often data about an element that you want to store with the element. In plain JavaScript, you might do this by adding a property to the DOM element, or by creating a closure, but you'd have to deal with memory leaks in some browsers. jQuery offers a straightforward way to store data related to an element, and it manages the memory issues for you.

Using $.fn.data

There are several forms of the $.fn.data function, which stores data into the elements found in the collection. Possible parameter lists are:

  • key, value - stores the value under the key for each element in the collection; the value can be any type of JavaScript value
  • object - stores all the properties of the object as data; basically a bulk form of the above method
  • key - retrieves the value stored under the key
  • no parameters - retrieves all the data as a single object with key-value pairs

$.fn.removeData(key) will remove the data stored under the key in the collection's elements. If no key is passed, all data will be removed.

$('#myDiv').data('myData', { foo : 'bar' });
$('#myDiv').data('myData'); // returns { foo : 'bar' }

You can store any kind of data on an element.

It's hard to overstate the importance of this when you get into complex application development. For the purposes of this class, we'll mostly use $.fn.data to store references to other elements.

For example, we may want to establish a relationship between a list item and a div that's inside of it. We could establish this relationship every single time we interact with the list item, but a better solution would be to establish the relationship once, and then store a pointer to the div in the list item using $.fn.data.

It's usually best to store data under single elements, either by using a query that finds only one element, or by using the $.fn.each function to establish unique data for each element in a collection.

Storing a Relationship Between Elements Using $.fn.data

$('#myList li').each(function() {
	var $li = $(this);
	var $div = $li.find('div.content');
	$li.data('contentDiv', $div);
});

// later, we don't have to find the div again;
// we can just read it from the list item's data
var $firstLi = $('#myList li:first');
$firstLi.data('contentDiv').html('new content');

In addition to passing $.fn.data a single key-value pair to store data, you can also pass an object containing one or more pairs.

Data vs. Closures

You can use a closure instead of data to remember values, but this approach isn't as flexible. With a closure, the values are held in a variable belonging to an enclosing function, and therefore only visible to that function and any other functions defined within it. Values stored with data are available to any code.

Usually closures are used within an iterating function passed to the each() method, so that the individual instance of the iterating function passed to a specific element can hold the closure for that element. Note that delegating event handlers cannot use closures to remember values, since there will not be a separate function defined for each item that triggers events. We will see delegating event handlers in an upcoming chapter.

$('#myList li').each(function() {
	var $li = $(this);
	var $div = $li.find('div.content');
	$li.click(function() {
		// we are within the scope of the function passed to each(),
		// so we can use a closure on the local variable $div
		$div.html('new content');
	});
});

Code Sample:

jqy-core/Demos/data-vs-closures.html
---- C O D E   O M I T T E D ----
jQuery(document).ready(function() {

	// Using data to remember a paragraph under an h2
	$('#dataDiv>h2').each(function() {
		var $h2 = $(this);
		var $p = $h2.next('p');		
		$h2.data('para', $p);		
	});

	// Later, from separate code, we don't have to find the p tag again,
	// we can just read it from the h2 element's data
	$('#dataHeading').click(
		function(e) {
			$(this).data('para').html('New Content from Data');
		}
	);

	// We can also access an element's data from totally unrelated code
	$('#other').click(
		function(e) {
			$('#dataHeading').data('para')
				.html('New Content from unrelated code');
		}
	);
		
	// Using closure
	$('#closureDiv>h2').each(function() {
		var $h2 = $(this);
		var $p = $h2.next('p');
		// Click handler using a closure of $p to find the paragraph
		$h2.click(
			function(e) {
				$p.html('New Content from Closure');
			}
		);
	});

	// But, there is no way to access that closure from code
	// outside of the each function above.
	
});

---- C O D E   O M I T T E D ----

Using Data

Click the heading above to see information from data.


Using Closures

Click the heading above to see information from closure.


Click here to access data from unrelated code.

We locate the first heading in the div#dataDiv and assign the next paragraph as data in the heading element. Later, we access this stored data in the heading element to update the content inside the paragraph.

Next, we access this stored data from separate code, updating the content inside the paragraph. This shows that we can access the stored data from anywhere in our code.

Finally, we create a click handler for the heading in the div#closureDiv, which modifies the contents with the next paragraph by referencing the $p variable through the closure method.

Using $.data

In addition to the data method for jQuery collections, there is also a utility method $.data(element, key, value), which stores data directly into the DOM element passed in. The behavior depends on the parameters passed in:

  • element, key, value - sets the value into the element's data under the key
  • element, key - gets the value stored in the element's data under the key
  • element - gets all the data stored in the element as a single object with key-value pairs

Since iterating through a collection using $.fn.each provides DOM elements, not jQuery objects, $.data can be effectively used to set unique data for each element when iterating.

$.data is also useful in event handlers, since they receive a reference to the element as this.

$.removeData(element, key) will remove the data stored under the key in that element. If no key is passed, all data will be removed.

Data stored with $.fn.data is accessible using $.data, and vice-versa. The following demo show the use of $.data in an each iteration. Since event handlers also receive the element as this, they can also make good use of $.data.

Code Sample:

jqy-core/Demos/data-vs-$-fn-data.html
---- C O D E   O M I T T E D ----
jQuery(document).ready(function() {
	
	$('#dataDiv>h2').each(function() {
		var $h2 = $(this);
		var $p = $h2.next('p');
		// since we had to create a collection $h2 to use next()
		// we might as well use $.fn.data on $h2
		$h2.data('para', $p);
		// but, we could do this instead
		//$.data(this, 'para', $p);
	});

	// Later, because the event handler has the DOM element as this,
	// and there is no other reason to create a collection,
	// we can use $.data
	$('#dataHeading').click(
		function(e) {
			$.data(this, 'para').html('New Content from Data');
		}
	);

});

---- C O D E   O M I T T E D ----

Using $.data

Click the heading above to see information from data.

When we first iterate through the headings, we have to create a collection $h2 in order to be able to call the next() function. So, we might as well us use $h2.data to store the data.

But, when we later set up event handling, the this value is a plain DOM element, which is exactly what $.data expects to work with.

DOM-Related Utilities

$.contains(container, contained)

The $.contains function returns true if contained is a descendant of container.

Feature and Browser Detection

Although jQuery eliminates most JavaScript browser quirks, there are still occasions when your code needs to know about the browser environment.

jQuery offers the $.support object, as well as the deprecated $.browser object, for this purpose. For complete documentation on these objects, visit http://api.jquery.com/jQuery.support/ and http://api.jquery.com/jQuery.browser/.

The $.support object is dedicated to determining what features a browser supports; it is recommended as a more "future-proof method of customizing your JavaScript for different browser environments".

The $.browser object was deprecated in favor of the $.support object, but it will not be removed from jQuery anytime soon. It provides direct detection of the browser brand and version.

Avoiding Conflicts with Other Libraries

If you are using another JavaScript library that uses the $ variable, you can run into conflicts with jQuery. In order to avoid these conflicts, you need to put jQuery in no-conflict mode immediately after it is loaded onto the page and before you attempt to use jQuery in your page.

When you put jQuery into no-conflict mode, you have the option of assigning a variable name to replace $.

Putting jQuery into No-conflict Mode

<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>var $j = jQuery.noConflict();</script></pre>
<p>You can continue to use the standard $ by wrapping your code in a self-executing anonymous function; this is a standard pattern for plugin authoring, where the author cannot know whether another library will have taken over the $.</p>
<h3>Using the $ Inside a Self-executing Anonymous Function</h3>
<pre class="brush: javascript;"><script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
jQuery.noConflict();
(function($) {
// your code here, using the $
})(jQuery);
</script>
Next