Barbarian Meets Coding
barbarianmeetscoding

WebDev, UX & a Pinch of Fantasy

10 minutes readjquery

jQuery

What is jQuery

jQuery is a JavaScript library that makes it very easy to:

  • operate and animate the DOM
  • fetch content via AJAX

by:

  • providing a standard to access the DOM that is consistent across different browsers
  • providing an easy API that wraps JavaScript

Basic jQuery

jQuery is based on using CSS selectors to select elements in the DOM and methods to perform operations on them. For instance:

jQuery('h1').text('Hello World') // set value of h1 to "Hello World"
$('h1').text('Hello world') // the $ sign is a short notation for jQuery

Whenever we use jQuery, it is important that we wait for the DOM to be fully loaded beforr we start interacting with it. To make sure of this, we use the ready method. The ready method lets us set a callback that will be executed when the DOM is fully loaded.

$(document).ready(function{
    // this is the jQuery ready event handler is executed when the DOM has been loaded
    $("h1").text("Hello world"); // set value of h1 to "Hello World"
});

Using Selectors

jQuery lets you use any CSS selector and pseudo classes to select all the elements in the DOM that match those selectors. For instace:

$('h1') // select all h1 elements
$('p') // select all paragraphs
$('.available') // select all elements with class 'available'
$('#main') // select element with id 'main'
$('ul#grocerylist li') // select all li elements inside a ul element with id grocerylist
$('ul#grocerylist > li') // select li elements that are direct descendants of ul element with id grocerylist
$('#grocerylist, .veggies') // select elements of id grocerylist or class veggies
$('ul#grocerylist li:first') // select first li that is a descendant of the ul element with id grocerylist
$('ul#grocerylist li:last')
$('ul#grocerylist li:even') // selects li elements with even index (0, 2, 4)
$('ul#grocerylist li:odd')

Traversing the DOM

Another method to select particular items in the DOM is traversing.

$('ul#grocerylist li') // descendant selector
$('ul#grocerylist').find('li') // traversing - find all li elements under the grocerylist
$('li:first') // pseudoclass selector
$('li').first() // traversing - get first li element
$('li:last') // pseudoclass selector
$('li').last() // traversing - get last li element

Traversing also allows you to walk the DOM via method chaining:

$('li')
  .first()
  .next() // next sibling
$('li')
  .last()
  .prev() // previus sibling
$('li')
  .first()
  .parent() // parent element
$('ul')
  .first()
  .children('li') // children - unlike find this selects direct children
$('li').parents('.awesome') // walk up the dom to find all ancestors of class awesome (returns all elements that satisfy that condition)
$('li').closest('.awesome') // walk up the dom to find the closest ancestor (returns 0 or 1 elements)

The point of using traversing is that it is faster than the alternative (via normal selectors).

Filtering the DOM via traversing

You can use traversing to filter node selections:

$('.groceries.onsale') // via css selectors
$('.groceries').filter('.onsale') //via traversing

Manipulating the DOM

These are the operations you can do to manipulate the DOM:

var message = $('<p>Hello! this is a paragraph</p>') // Create paragraph element
// add element as a child of div#screen and at the end of the children tree
$('div#screen').append(message)
message.appendTo($('div#screen'))
// add element as a child of div#screen and at the beginning of the children tree
$('div#screen').prepend(message)
message.prependTo($('div#screen'))
// add element as a sibling of the first paragraph and after it
$('div#screen p:first').after(message)
message.insertAfter($('div#screen p:first'))
// add element as a sibling of the first paragraph and before it
$('div#screen p:first').before(message)
message.insertBefore($('div#screen p:first'))
// remove first paragraph
$('p:first').remove()

Styling the DOM

You can explicitly set the css of elements via the css method:

$("p:first").css(<attribute>, <value>); // set attribute
$("p:first").css(<attribute>); // get attribute
$("p:first").css(<object>); // set several attributes at once

Or you can add, remove and toggle classes of elements (which is a better practice since it helps enforcing the separation of concerns between behavior - javaScript - and styling - CSS):

$('p:first').addClass('highlighted')
$('p:first').removeClass('highlighted')
$('p:first').toggleClass('highlighted')
$('p:first').hasClass('highlighted')

Animating the DOM

You can hide and show elements with different animations as well:

$('p:first').hide()
$('p:first').show()
$('p:first').slideDown()
$('p:first').slideUp()
$('p:first').slideToggle()
$('p:first').fadeIn()
$('p:first').fadeOut()
$('p:first').fadeToggle()

You can also had specific animations via the animation method:

$('p:first').animate({ top: '10px' }) // changes css property in an animated manner
$('p:first').animate({ top: '10px' }, 400) // you can explicitely set the speed of the animation in milliseconds
$('p:first').animate({ top: '10px' }, 'fast') // or with a special string 'fast', 'slow', etc
$('p:first').animate({ top: '10px' }, 200)
$('p:first').animate({ top: '10px' }, 'slow')
$('p:first').animate({ top: '10px' }, 600)

Today, you can specify most animations using CSS3 transitions and CSS3 animations. However you still need to use vendor prefixes and “modern” browsers for it to work.

Interacting with events in the DOM

Event handling with jQuery usually takes the shape of $("element").method(eventHAndler) or $("element").on(eventName, eventHandler).

$("button").on("click", function() {
    // callback that runs when any button is clicked
});
$("button").click(function(){ ... })

We can use the $(this) to refer to the element that triggered the event inside an event handler.

Using event delegation

Using event delegation we limit the elements that we associate to events:

$(".groceries").on("click", "button", function() {//...});

Using event arguments

Every event in jQuery gets passed the same event argument:

$('button').on('click', function(event) {
  // callback that runs when any button is clicked
})

Interesting methods we can use in event arguments are:

  • stopPropagation: to prevent the event from bubbling up the DOM
  • preventDefault: to prevent the default behavior from the browser

More about jQuery events

You can find all jQuery events at jquery.com. And more specifically:

Debugging jQuery

The simplest way to debug your jQuery is to use the alert(message) or console.log(message) JavaScript methods.

Another useful way to see if your jQuery selectors are working as expected is to use the length property that will return how many nodes of a given selection are on a page.

$('li').length // returns how many <li> exist in the page

Advanced jQuery

Reading from the DOM

Read the contents of the DOM by using a selector and the methods:

  • html(): To obtain the full html for the selection
  • text(): To obtain the text (value) of the HTML elements in that selection
  • attr(): To obtain the value of an attribute of the HTML elements in that selection
  • data(): To obtain the value of a data tag of the HTML elements in the selection
  • val(): To obtain the value of input elements

Ensuring that $ is namespaced to jQuery

Use the following syntax that executes when the DOM has been loaded correctly:

jQuery(function($) {
  // code
})

AJAX with jQuery

Basic AJAX

// simplified AJAX request via get method
$.get("/swords",
      {weight: swordWeight},
      function(result){
        $("div#catalog").html(result);
});
// full-blown AJAX request via ajax method
$.ajax('/swords', {
       data: {weight: swordWeight},
       cache: false,
       timeout: 8000, // After 8 seconds trigger timeout error
       dataType: 'json', // We are expecting json in the response
       beforeSend: function(result){ // before AJAX is invoked
        $("#error").hide();
        $("#loading").show();
        },
       complete: function(){  // when AJAX returns
        $("#loading").hide();
        },
       success: function(result){  // if AJAX returns successfully
        $("#catalog").html(result);
        },
       error: function(result){  // if AJAX doesn't return successfully
        $("#error").show();
        }
    }
});
// simplified AJAX request to get JSON
$.getJSON(...)

You can cancel an AJAX call via the abort() method.

var ajaxCall = $.ajax(...);
ajaxCall.abort();

Note that, when abort() triggers the error callback of an AJAX call:

var ajaxCall = $.ajax(...
        error: function(result){
            if (result.statusText != "abort") alert("AJAX call was aborted!");
        },
        ...);

JSON

JSON (JavaScript Object Notation) is a lighweight data interchange format commonly used in web services.

Since it is just a JavaScript object, you can directly use the returned JSON object and access any of its members:

$.ajax('/swords', {
       data: {id: swordId},
       dataType: 'json',
       success: function(json){  
            alert("Behold! I wield the " + json.name + " with " + json.die + "damage!!!");
        },
    }
});

JSONP

When you fetch data from a different domain you normally use JSONP.

$.ajax('/swords', {
       data: {id: swordId},
       dataType: 'jsonp', // Note the jsonP dataType!
       success: function(json){  
            alert("Behold! I wield the " + json.name + " with " + json.die + "damage!!!");
        },
    }
});

Sending data with AJAX post calls

You can send information to a web service by using AJAX with a postrequest:

var formData = $(#login).serialize(); // serializes form
$.ajax('/login', {
       data: formData,
       dataType: 'script',
       type: 'post'
    }
});

Effects

Chaining Effects and Adjusting Speed

$("#login").fadeOut().html(...).fadeIn(); // doesn't wait for the end of fadeOut to change the html
$("#login").fadeOut("fast", function(){ // waits for the fadeOut to complete before executing the callback
    $(this).html(...).fadeIn("slow");
})

Effect Easing

jQuery offers two easing effects by default: linear and swing. jQuery UI comes with a lot of easing effects.

$('#login').fadeOut(1000, 'swing')

Queueing Effects

We can queue effects by using the queue method like illustrated bellow:

$('#login').queue(function(next) {
  $(this)
    .html('...')
    .fadeIn('slow')
  next() // use next to dequeue the next item
})

Delay Effects

You can delay effects by using the delay method:

$('#toast')
  .delay(1000)
  .fadeIn()

You can also use the stop method to stop any effect at any time.

jQuery Helpers

jQuery offers several helpers like $.each for traversing collections:

$.each(swords, function(index, sword){
    ...
});

and $.map to perform transformations:

$.map(swords, function(sword){
    ...
});

Create Your Own Helpers

You can easily extend jQuery with your own helpers (methods not called on jQuery objects but called just by using the $. notation):

;(function($) {
  $.sayHi = function() {
    alert('Yo! Wazzzup!')
  }
})(jQuery)
$.sayHi()

You can also create plugins that extend jQuery and are called on jQuery objects as in:

;(function($) {
  $.fn.beAwesome = function() {
    this.css({ opacitiy: 0.5 }).animate({ opacity: 1 }, 'fast')
  }
})(jQuery)
$('#barney').beAwesome()

Create Your Own Events

You can create your custom events by:

  1. binding events to jQuery objects as usual
  2. triggering this custom events via the trigger method

Using Defaults with jQuery

You can handle default values within methods very easily with jQuery by using the extend method:

var options = $.extend(defaults, options) // extend the options object with the defaults object

Encapsulating Your JQuery

As usual with any JavaScript, it is helpful to encapsulate any jQuery that you have in objects to avoid name collisions.

jQuery Resources


Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.Jaime González García