jQuery quick-reference
The jQuery function
The jQuery function can operate on DOM elements in many ways:
- find and select
- change/alter content
- listen to events
- animate
- perform network requests
The function call syntax is jQuery()
or the more concise $()
Loading jQuery
We can load the jQuery library w/ a <script>
tag: <script type='text/javascript' src='<jQuery url>'>
; we can then write our jQuery-powered functions in a separate file, which we'll load after the library.
Enabling jQuery on document.ready
We need to make sure the DOM has finished loading the HTML content before we can reliably use jQuery.
We'll initialize our jQuery code this way:
jQuery(document).ready(function() {
// code
});
Selecting DOM elements
jQuery can select elements much like CSS:
$('')
- type selector
- class selector
- ID selector
- child selector
- descendant selector
- …
There are also built-in, CSS-like pseudo-classes:
:first
:last
:even
(zero-based):odd
(zero-based):gt(<index>)
Select all elements at an index greater than within the matched set.
To select multiple elements, we just have to separate them with a comma, like arguments:
$('.class, #id')
DOM Traversal
Instead of directly selecting elements, we can traverse the DOM via a series of methods:
- get ancestors
.parent()
-- selects the parent element, only travels a single level up the DOM tree.parents()
-- returns all of the ancestors of a given element.closest()
-- "Travels up the DOM tree until it finds a match for the supplied selector", returns 0 or 1 of the ancestors
- get descendants
.children()
-- selects children elements.find()
-- "Get the descendants of each element […], filtered by a selector […]"
.first()
-- finds the first element.last()
-- finds the last element.next()
-- finds the next element.prev()
-- finds the previous element.filter()
-- "Reduce the set of matched elements to those that match the selector or pass the function's test."
Traversing is faster than selecting.
Examples
selection | traversal
$('').method()
$('#id').parent()
$('.class').first().parent()
-- this pattern is called "method chaining"
Working with the DOM
We can manipulate the DOM via a series of dedicated methods:
.append()
.prepend()
.after()
.before()
.remove()
.addClass()
-- adds a CSS class.removeClass()
-- removes a CSS class- w/ "reversed" syntax:
.appendTo()
.prependTo()
.insertAfter()
.insertBefore()
Example
Given this HTML:
<div id="tours">
<h1>Guided Tours</h1>
<ul>
<li class="usa tour">
<h2>New York, New York</h2>
<span class="details">$1,899 for 7 nights</span>
<button class="book">Book Now</button>
</li>
</ul>
</div>
We want to add <span>Call 1-555-jquery-air to book this tour</span>
before button.book
. Here's how we can do it with jQuery:
jQuery(document).ready(function() {
// first we generate our DOM node and assign it to a variable
var insertion = $('<span>Call 1-555-jquery-air to book this tour</span>');
// then we place the element where desired; notice we first select the insertion point
$('.book').after(insertion);
});
Using .insertAfter()
the syntax is reversed, with the reference point at the beginning:
jQuery(document).ready(function() {
var insertion = $('<span>Call 1-555-jquery-air to book this tour</span>');
insertion.insertAfter($('.book'));
});
Useful methods
- CSS manipulation
.css(<attr>, <value>)
.css(<attr>)
.css(<object>)
.addClass()
.removeClass()
.toggleClass()
.hasClass()
-- Determine whether any of the matched elements are assigned the given class, returns a boolean value
- animation
.animate(<object>, <speed>)
.show()
.hide()
.slideDown()
.slideUp()
.slideToggle()
-- display or hide the matched elements with a sliding motion..fadeIn()
.fadeOut()
.fadeToggle()
$('<selector>').length
-- finds how many nodes of the given type are present in the DOM- data manipulation
.serialize()
-- when listening for formsubmit
events, merges all the submitted data
- other
.attr()
-- gets or sets (w/ additional argument) an HTML attribute.data()
-- reads or sets<data>
attributes.data(<data-attr>)
: reads -- notice that thedata-
prefix is not needed in the selector.data(<data-attr>, <data-value>)
: sets
.html()
-- no args, will "Get the HTML contents of the first element in the set of matched elements.".html(<html string or function>)
will "Set the HTML contents of each element in the set of matched elements."
.detach()
removes an element from the DOM, preserving all data and events. This is useful to minimize DOM insertions with multiple html elements. […] it's the same as.remove()
, except that.detach()
keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time..empty()
-- no args, will Remove all child nodes of the set of matched elements from the DOM
Examples of CSS manip
// <attr>, <value>
$(element).css('background-color', 'teal');
// <object>
$(element).css({
// we're passing key-value pairs as object properties
'background-color': 'teal',
'border': '1px solid black'
});
Examples of jQuery animation
// w/o speed
$(element).animate({'top': '-10px'});
// w/ speed, as a string (`fast`/`slow`) or as a number in milliseconds
$(element).animate({'top': '-10px'}, 400);
$(element).animate({'top': '-10px'}, 'fast');
Listening for events
The jQuery .on()
method allows us to listen to events, and act on them:
.on('<event>', <event handler function>)
Example
If we wanted to add an event listener for clicks on all buttons, based on the HTML in the example above:
jQuery(document).ready(function() {
// we select all buttons and attach an event listener
$('button').on('click', function() {
var message = $('<span>Call 1-555-jquery-air to book this tour</span>');
$('.usa').append(message);
$('button').remove();
});
});
.on()
can also accept a third argument:
.on('<event>', <selector>, <event handler function>)
A selector string to filter the descendants of the selected elements that trigger the event.
Example
$('.my-class').on('click', 'button', function() { // });
Enables the event handler for only the <button>
elements inside .my-class
elements.
This technique is called event delegation -- we listen for events on the outer element, but the handler will be triggered only for a specified inner element(s).
Finally, the callback passed to .on()
can receive an event argument:
.on('<event>', '<element>,' function(e) { // });
The event argument lets us log or control browser events, for example:
e.stopPropagation()
-- prevents event bubblinge.preventDefault()
-- prevents the browser's default behavior with the given event (For example, clicked anchors will not take the browser to a new URL.)console.log(e)
-- logs the event
The .off() method
The .off(<events>, <selector>, <handler>)
method will stop watching for the given event:
The
.off()
method removes event handlers that were attached with.on()
. […] Calling.off()
with no arguments removes all handlers attached to the elements. Specific event handlers can be removed on elements by providing combinations of event names, namespaces, selectors, or handler function names. […]
Example
$(document).ready(function(){
$('button').on('click', function() {
var results = $(this).closest('li').find('.results');
results.append('<p>Weather: 74°</p>');
// to avoid an endless cycle of `.append()`s on click, we deactivate the ev. listener after the 1st interaction
$(this).off('click');
});
});
Event namespacing
We can label our events like this:
$('button').on('click.event-id', function() {});
Now we can selectively deactivate events w/ .off()
, by passing in our custom identifier:
// notice how the syntax is similar to the class selector
$('button').off('.event-id');
The .trigger() method
.trigger(<ev. type>, <additional params>)
will: "Execute all handlers and behaviors attached to the matched elements for the given event type."
Any event handlers attached with
.on()
or one of its shortcut methods are triggered when the corresponding event occurs. They can be fired manually, however, with the.trigger()
method. A call to.trigger()
executes the handlers in the same order they would be if the event were triggered naturally by the user […]
With .trigger()
we can manually fire events, independently of user interaction. This is useful also in case of custom events:
Any event names can be used for the events argument. jQuery will pass through the browser's standard JavaScript event types, calling the handler function when the browser generates events due to user actions such as
click
. In addition, the.trigger()
method can trigger both standard browser event names and custom event names to call attached handlers. Event names should only contain alphanumerics, underscore, and colon characters.
Example w/ standard events
$(document).ready(function(){
// triggers a click event on button prior to any user interaction
$('button').trigger('click');
$('button').on('click.weather', function() {
var results = $(this).closest('li').find('.results');
results.append('<p>Weather: 74°</p>');
$(this).off('click.weather');
});
});
Example w/ custom events
$(document).ready(function(){
// we define a custom name for the event
$('button').on('show.weather', function() {
var results = $(this).closest('li').find('.results');
results.append('<p>Weather: 74°</p>');
$(this).off('show.weather');
});
$('button').on('click.photos', function() {
var tour = $(this).closest('li');
var results = tour.find('.results');
results.append('<p><img src="/assets/photos/'+tour.data('loc')+'.jpg" /></p>');
// we call and trigger the prev custom event
$(this).trigger('show.weather');
$(this).off('click.photos');
});
});
Using this in jQuery
Based on the prev example:
<div id="tours">
<h1>Guided Tours</h1>
<ul>
<li class="usa tour">
<h2>New York, New York</h2>
<span class="details">$1,899 for 7 nights</span>
<button class="book">Book Now</button>
</li>
</ul>
</div>
<script type='text/javascript'>
jQuery(document).ready(function() {
$('button').on('click', function() {
var message = $('<span>Call 1-555-jquery-air to book this tour</span>');
$(this).after(message);
$(this).remove();
});
});
</script>
In this case, this
refers to the element that triggered the event. Notice we can't use the plain this
keyword, we have to wrap it: $(this)
Common DOM events
- mouse
click
dblclick
focusin
focusout
mousedown
mouseup
mousemove
mouseout
mouseover
mouseleave
mouseenter
- Keyboard
keypress
keydown
keyup
- Form
blur
focus
select
submit
change
.val()
,.val('<value>')
-- "Get the current value of the first element in the set of matched elements or set the value of every matched element. The .val() method is primarily used to get the values of form elements such as input, select and textarea […]"
AJAX
AJAX, or Asynchronous JavaScript And XML, is a client side technique for communicating with a web server that lets us update parts of a webpage w/o performing a full page reload. An AJAX request in jQuery is constructed as follows:
$.ajax(<url>, {<settings>});
The url argument is defined as:
A string containing the URL to which the request is sent.
The settings argument is an object, which contains:
A set of key/value pairs that configure the Ajax request. All settings are optional.
The settings object can contain functions as values (methods). These callbacks can receive a response
argument -- required in the success
callback in order to update our page with the results of the request.
The shorthand method with $.get()
With $.get()
we can perform an AJAX request in a more concise way: $.get(<url string>, <success function>)
$.get('example.com', function(response) {
<jQuery selector>.html(response).<actions we want to perform>;
})
A typical AJAX request
A typical AJAX request is comprised of many parts, let's see them in detail:
$.ajax('example.com/load.html', {
type: <value>,
contentType: <value>,
dataType: <value>,
data: <value>,
context: <value>,
success: <callback>,
error: <callback>,
timeout: <number value>,
beforeSend: <callback>,
complete: <callback>
});
The breakdown:
type: <value>
-- obsolete, usemethod:
instead -- the HTTP method to use for the request (i.e.GET
,POST
,PUT
)contentType: <value>
default:'application/x-www-form-urlencoded; charset=UTF-8'
-- if we want a JSON response:'application/json'
dataType: <value>
the type of data we're expecting back from the serverdata: <value>
data to be sent to the servercontext: <value>
the context of all Ajax-related callbackssuccess: <callback>
action to perform if the request is successfulerror: <callback>
action to perform if the request is not successfultimeout: <number value>
number value for request timeout, in millisecondsbeforeSend: <callback>
action to perform before the request is sent (i.e. display a loading animation)complete: <callback>
action to perform at the end of the cycle, whether or not the request was successful
Example
$(document).ready(function() {
$("#tour").on("click", "button", function() {
$.ajax('/photos.html', {
success: function(response) {
$('.photos').html(response).fadeIn();
},
error: function() {
$('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
},
timeout: 3000,
beforeSend: function() {
$("#tour").addClass('is-fetching');
},
complete: function() {
$("#tour").removeClass('is-fetching');
}
});
});
});
Focus: data
and context
data
, from jQuery documentation:
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. […]
context
, from jQuery documentation:
This object will be the context of all Ajax-related callbacks. By default, the context is an object that represents the Ajax settings used in the call […]. For example, specifying a DOM element as the context will make that the context for the complete callback of a request […]
With context
we can override the value of this
in our AJAX callbacks; this
by default would be referred to the AJAX settings.
Example AJAX call w/ context
function Tour(el) {
// this = object that the constructor will create
var tour = this;
// we save a reference to the passed-in parameter
// the objects we'll generate from this constructor will have a property of el: el
this.el = el;
this.fetchPhotos = function() {
$.ajax('/photos.html', {
/*
we set the context of all the following callbacks;
in other words, we override the value of this,
which by default would be referred to the AJAX settings
*/
context: tour,
data: {location: $(tour.el).data('location')},
success: function(response) {
$(this.el).find('.photos').html(response).fadeIn();
},
error: function() {
$(this.el).find('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
},
timeout: 3000,
beforeSend: function() {
$(this.el).addClass('is-fetching');
},
complete: function() {
$(this.el).removeClass('is-fetching');
}
});
};
this.el.on('click', 'button', this.fetchPhotos);
}
$(document).ready(function() {
var paris = new Tour($('#paris'));
});
The $.getJSON method
$.getJSON(<url>, <data>, <success callback>)
Load JSON-encoded data from the server using a GET HTTP request. This is a shorthand Ajax function, which is equivalent to:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Utility methods
$.each()
$.each(<collection>, function(<index>, <element>) {})
Runs a function for each element in the collection, returns the original collection unchanged
Example
var myArray = [1, 2, 3, 4];
$.each(myArray, (ind, el) => {
let result = el + 10;
console.log(result);
});
/*
11
12
13
14
Array [ 1, 2, 3, 4 ]
*/
$.map()
$.map(<collection>, function(<element>, <index>) {})
- Runs a function for each element in the collection, creates a new collection from the returned results -- the original collection stays intact
- Notice that, while the structure of the call is nearly identical to
each()
, the order of the arguments is inverted!
Example
var myArray = [1, 2, 3, 4];
$.map(myArray, (el, ind) => {
let result = el + 10;
console.log(result);
return result;
});
/*
11
12
13
14
Array [ 11, 12, 13, 14 ]
*/
$.extend()
Merge the contents of two or more objects together into the first object. When two or more object arguments are supplied to
$.extend()
, properties from all of the objects are added to the target object.
$.extend(<target>, <obj-1>, <obj-n>)
jQuery Plugins
A jQuery plugin is simply a new method that we use to extend jQuery's prototype object. By extending the prototype object you enable all jQuery objects to inherit any methods that you add.
Sometimes you want to make a piece of functionality available throughout your code. For example, perhaps you want a single method you can call on a jQuery selection that performs a series of operations on the selection. In this case, you may want to write a plugin.
We create a plugin with this syntax:
$.fn.plugin-name = function() {
//
};
We then can call our plugin like a regular function:
$(<selector>).plugin-name();
the $.fn object
Whenever you use the
$
function to select elements, it returns a jQuery object. This object contains all of the methods you've been using and all of the elements that fit your selector. The jQuery object gets these methods from the$.fn
object.
By creating a plugin we're effectively adding to the $.fn
object, i.e. jQuery's parent object -- (see similarities w/ JS prototypes).
// enter this in the browser's console
$.fn
// output
Object { jquery: "1.11.3", constructor: function jQuery(), selector: "", length: 0, toArray: function toArray(), get: function get(), pushStack: function pushStack(), each: function each(), map: function map(), slice: function slice(), … }
jQuery promises
With promises we can abstract AJAX calls into modules we can use throughout our code. AJAX requests in fact return objects of type Promise:
The
jqXHR
objects returned by$.ajax()
as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information). The jQuery XMLHttpRequest (jqXHR
) object returned by$.ajax()
as of jQuery 1.5 is a superset of the browser's nativeXMLHttpRequest
object
But what if we wanted to build a custom Promise obj from scratch?
Introducing the $.Deferred() method:
The $.Deferred()
method returns a Deferred object:
The Deferred object, introduced in jQuery 1.5, is a chainable utility object created by calling the
jQuery.Deferred()
method. It can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
A Deferred object starts in the pending state. Any callbacks added to the object with
deferred.then()
,deferred.always()
,deferred.done()
, ordeferred.fail()
are queued to be executed later. Callingdeferred.resolve()
ordeferred.resolveWith()
transitions the Deferred into the resolved state and immediately executes anydoneCallbacks
that are set. Callingdeferred.reject()
ordeferred.rejectWith()
transitions the Deferred into the rejected state and immediately executes anyfailCallbacks
that are set. Once the object has entered the resolved or rejected state, it stays in that state. Callbacks can still be added to the resolved or rejected Deferred — they will execute immediately.
Main methods available to the Deferred object:
deferred.resolve(<args>)
- Resolve a Deferred object and call any doneCallbacks with the given
args
.
- Resolve a Deferred object and call any doneCallbacks with the given
deferred.done(<doneCallbacks>)
- When the Deferred is resolved, doneCallbacks are executed using the arguments provided to the
resolve
method
- When the Deferred is resolved, doneCallbacks are executed using the arguments provided to the
deferred.reject(<args>)
- Reject a Deferred object and call any failCallbacks with the given
args
.
- Reject a Deferred object and call any failCallbacks with the given
deferred.fail(<failCallbacks>)
- When the Deferred is rejected, the failCallbacks are executed using the arguments provided to the
deferred.reject()
- When the Deferred is rejected, the failCallbacks are executed using the arguments provided to the
So, deferred.done()
and deferred.fail()
can use the same args as deferred.resolve()
and deferred.reject()
!
Example
Given this HTML:
<div class="vacation-location">
<h3 class="location">London, UK</h3>
<p class="price"></p>
<button>Update Price</button>
</div>
And this starter JS code:
$(document).ready(function(){
$('button').on(click, function(){
var location = $('.location').text();
$.ajax('/vacation/prices', {
data: {q: location},
success: function(result){
$('.price').text(result.price);
}
});
});
});
We can abstract our code's AJAX req into a new object with a getPrice()
method, which contains our promise:
Defining our promise w/ $Deferred()
var Vacation = {
getPrice: function(location){
// We create a Deferred obj
var promise = $.Deferred();
$.ajax('/vacation/prices', {
data: {q: location},
success: function(result){
// we use Deferred's resolve() method
promise.resolve(result.price);
},
error: function(){
var error = 'invalid location';
// we use Deferred's reject() method
promise.reject(error);
}
});
return promise;
}
}
Invoking our promise
$(document).ready(function() {
$('button').on('click', function(){
var location = $('.location').text();
// the method we're storing in our var returns the Deferred obj:
// therefore we're storing the Deferred obj in our var
// we're also passing the location arg we dynamically built at line 3
var usePromise = Vacation.getPrice(location);
// we invoke the done method, using the same args as resolve
// result is in fact result.price
usePromise.done(function(result){
$('.price').text(result);
});
// we invoke the fail method, using the same args as reject
usePromise.fail(function(error){
console.log(error);
});
});
});
Combining multiple Deferred objects with $.when()
$.when()
, combined with .then()
(notice, not jQuery.then()
) allows us to define an execution order for our Promises, so that we can avoid unwanted repercussions on page layout/performance.
$.when()
provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.
Example
Expanding on the above example, if we were to use another Deferred object:
var Photo = {
getPhoto: function(location){
var promise = $.Deferred();
$.ajax('/vacation/photos', {
data: {q: location},
success: function(result){
promise.resolve(result.url);
}
});
return promise;
}
}
And we wanted it to load together with our main object, we could proceed like this:
Solution
$(document).ready(function() {
$('button').on('click', function(){
var tour = $(this).parent();
var location = tour.data('location');
var resultDiv = tour.find('.results').empty();
$.when(
// args are the actual Deferred objects
// now the code will wait until the 2 calls are finished
// then it'll call the .then callbacks
Vacation.getPrice(location),
Photo.getPhoto(location)
// callback data in the same order as the Deferred objects
// now the data is rendered at the same time, and in the specified order
).then(function(priceResult, photoResult) {
$('<p>$'+priceResult+'</p>').appendTo(resultDiv);
$('<img />').attr('src', photoResult).appendTo(resultDiv);
});
});
});