Tuesday, January 13, 2015

Jquery Advanced Best Practices

1. Always Descend From an #id

This is the golden rule of the jQuery selectors. The fastest way to select an element in jQuery is by ID:

$('#content').hide();
or select multiple elements descending from an ID:
$('#content p').hide();

2.Use Tags Before Classes

The second fastest selector in jQuery is the Tag selector ($(‘head’)) because it maps to a native JavaScript method, getElementsByTagName(). The best way is to prefix a class with a tag name (and descend from an ID):

var receiveNewsletter = $('#nslForm input.on');
The class selector is among the slowest selectors in jQuery; in IE it loops through the entire DOM. Avoid using it whenever possible. Never prefix an ID with a tag name. For example, this is slow because it will loop through all <div> elements looking for the ‘content’ ID:

var content = $('div#content'); // VERY SLOW, AVOID THIS
Also, DON’T descend from multiple IDs:

var traffic_light = $('#content #traffic_light'); // VERY SLOW, AVOID THIS

Cache the parent object then run queries on it:

var header = $('#header');
var menu = header.find('.menu');
menu = $('.menu', header);

4. Optimize selectors for Sizzle’s ‘right to left’ model

var linkContacts = $('.contact-links div.side-wrapper');

instead of:

var linkContacts = $('a.contact-links .side-wrapper')

5. Use find() rather than context

var divs = $('.testdiv', '#pageBody'); 

var divs = $('#pageBody').find('.testdiv');

var divs = $('#pageBody .testdiv');

5. Use direct functions rather than their convenience counterparts

For better performance you can use direct functions like $.ajax() rather than $.get(), $.getJSON(), $.post() because the last ones are shortcuts that call the $.ajax() function

6.Use shorcuts 

Consider, below jQuery code lines.

$("#elm").css("display", "none"); //Line 1

$("#elm").css("display", ""); //Line 2

$("#elm").html(""); //Line 3

Above code lines are very common but its unfortunate because some faster and more readable shortcuts available, yet ignored. Find below jQuery code lines that does the exactly same thing but these are more readable and fast.

$("#elm").hide(); //Line 1

$("#elm").show(); //Line 2

$("#elm").empty(); //Line 3

There are many more examples which you can find in your code. For example, to add CSS Class to any element

$("#elm").prop("class", "cssClass");

where the better approach would be,
$("#elm").addClass("cssClass");

Another example is of setting height and width,

$("#elm").css("height", "100px"); //Line 1

$("#elm").css("width", "100px"); //Line 2

using in-built jQuery functions,

$("#elm").height(100); //Line 1

$("#elm").width(100); //Line 2

Another common situation is of toggling (show/hide) of element. For example, 

if($("#elm").is(":visible")) 
    $("#elm").css("display", "none");
else 
    $("#elm").css("display", "");
where the better approach is,
$("#elm").toggle();


to be continued . . . .:)

Jquery Best practice - Event Handling

  We usually do this :

$("#longlist li").on("mouseenter", function() {

    $(this).text("Click me!");

  });


  $("#longlist li").on("click", function() {

    $(this).text("Why did you click me?!");

  });

This is fine IF...

If you like using a lot of memory for event handlers
If you don't have many DOM elements
If you don't care about best practices


Best Approach : Event Delegation 


var list = $("#longlist");

  list.on("mouseenter", "li", function(){

    $(this).text("Click me!");

  });

  list.on("click", "li", function() {

    $(this).text("Why did you click me?!");

  });

Simple but thoughtful :)

Try n feel the difference...

JQuery Best Practices - DOM Manipulation


  Usually we folllow like this ..

 // Set's an element's title attribute using it's current text
  $(".container input#elem").attr("title", $(".container input#elem").text());

  // Set's an element's text color to red
  $(".container input#elem").css("color", "red");

  // Makes the element fade out
  $(".container input#elem").fadeOut();

This is fine if ..

If you like repeating yourself
If you do not care about performance
If you don't care about best practices

  Best Approach.. 

  // Stores the live DOM element inside of a variable

  var elem = $("#elem");

  // Set's an element's title attribute using it's current text
  elem.attr("title", elem.text());

  // Set's an element's text color to red
  elem.css("color", "red");

  // Makes the element fade out
  elem.fadeOut();

cache your selectors in variables :)

Another Example 

 Mostly we prefer doing like this ..

// Dynamically building an unordered list from an array

  var localArr = ["Greg", "Peter", "Kyle", "Danny", "Mark"],
 
  list = $("ul.people");

  $.each(localArr, function(index, value) {

    list.append("<li id=" + index + ">" + value + "</li>");

  });

// Dynamically building an unordered list from an array
  var localArr = ["Greg", "Peter", "Kyle", "Danny", "Mark"],
  list = $("ul.people"),
  dynamicItems = "";

  $.each(localArr, function(index, value) {

    dynamicItems += "<li id=" + index + ">" + value + "</li>";

  });

  list.append(dynamicItems);


 Append only once instead of doing it every time ..:)

Jst try :) 

JQuery Best Practices - Document ready

Most projects starts like this

$("document").ready(function() {
    // The DOM is ready!
    // The rest of the code goes here
  });

This is fine if

If you know the environments where your code will run
If you do not care about page load performance
If you don't care about best practices

This is better

// IIFE - Immediately Invoked Function Expression

  (function($, window, document) {

    // The $ is now locally scoped

   // Listen for the jQuery ready event on the document
   $(function() {

     // The DOM is ready!

   });

   // The rest of the code goes here!

  }(window.jQuery, window, document));

  // The global jQuery object is passed as a parameter

---------------------------------------------------------------------------------------------------------