jQuery quick-reference

  • Using this in jQuery
  • Common DOM events
  • AJAX
  • Utility methods
  • jQuery Plugins
  • jQuery promises
  • 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 form submit 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 the data- 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 bubbling
    • e.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&deg;</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&deg;</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&deg;</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, use method: 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 server
    • data: <value> data to be sent to the server
    • context: <value> the context of all Ajax-related callbacks
    • success: <callback> action to perform if the request is successful
    • error: <callback> action to perform if the request is not successful
    • timeout: <number value> number value for request timeout, in milliseconds
    • beforeSend: <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 native XMLHttpRequest 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(), or deferred.fail() are queued to be executed later. Calling deferred.resolve() or deferred.resolveWith() transitions the Deferred into the resolved state and immediately executes any doneCallbacks that are set. Calling deferred.reject() or deferred.rejectWith() transitions the Deferred into the rejected state and immediately executes any failCallbacks 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.
    • deferred.done(<doneCallbacks>)
      • When the Deferred is resolved, doneCallbacks are executed using the arguments provided to the resolve method
    • deferred.reject(<args>)
      • Reject a Deferred object and call any failCallbacks with the given args.
    • deferred.fail(<failCallbacks>)
      • When the Deferred is rejected, the failCallbacks are executed using the arguments provided to the deferred.reject()

    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);
      });
      });
    });