SlideShare a Scribd company logo
Advan
 ced
Sergi
  o
Pereir
Sergio
•http://
sergiopereira.com/
blog        look

•@sergiopereira
•Chicago ALT.NET
•Chicago Code
The Plan
•not just Tips &
Tricks but, yeah,
some of those
•overlooked jQuery
features
•coding the jQuery
The Plan
Is Subject To
   Change
Quick
Wins
end()
breadcrumbs for
your navigation
end() Command

<div class=menu>
 <ul>
    <li class=current>New</li>
    <li>Open...</li>
    <li>Print...</li>
 </ul>
</div>
<div class=menu>
 ...
</div>
end() Command
$('.menu').find('li')



      <div class=menu>
       <ul>
          <li class=current>New</li>
          <li>Open...</li>
          <li>Print...</li>
       </ul>
      </div>
      <div class=menu>
       ...
      </div>
end() Command
$('.menu').find('li')
       .filter('.current')

      <div class=menu>
       <ul>
          <li class=current>New</li>
          <li>Open...</li>
          <li>Print...</li>
       </ul>
      </div>
      <div class=menu>
       ...
      </div>
end() Command
$('.menu').find('li')
       .filter('.current')
       .end()
      <div class=menu>
       <ul>
          <li class=current>New</li>
          <li>Open...</li>
          <li>Print...</li>
       </ul>
      </div>
      <div class=menu>
       ...
      </div>
end() Command
$('.menu').find('li')
       .filter('.current')
       .end().end()
      <div class=menu>
       <ul>
          <li class=current>New</li>
          <li>Open...</li>
          <li>Print...</li>
       </ul>
      </div>
      <div class=menu>
       ...
      </div>
Computed
for when a simple
 expression isn’t
     enough
Computed Values

$('#buttons li')
 .css('margin-left', function(ix, val) {

        return ix*10;
  });
Computed Values
• attr(name,
 function(i,v){ })
• prop(name,
 function(i,v){ })
• val(function(i,v){ })
• css(name,
 function(i,v){ })
Relative CSS
  incremental
Relative CSS

$('#volumeUp').click(function(){
    var $volBar = $('#volBar');
    var width = $volBar.css('width');
    //easy mistake
    $volBar.css('width', width + 10);
});
Relative CSS

$('#volumeUp').click(function(){
    $('#vol').css('margin-left', '+=10');
});
data()
goodbye memory
     leaks
data() Storage
var myForm = $('#myform')[0];
var formResult = {
   errors: validateForm(myForm),
   form: myForm
};
myForm.result = formResult;

//later...
var result = $('#myform')[0].result;
if(result.errors.length){
   alert('Fix the errors.');
}
data() Storage
var formResult = {
   errors: validateForm(myForm),
   form: $('#myform')
};
$('#myform').data('result', formResult);

//later...
var result = $('#myform').data('result');
if(result.errors.length){
   alert('Fix the errors.');
}
data() Storage
  <ul>
   <li data-movie-id="131">Crash</li>
   <li data-movie-id="722">Up</li>
  </ul>


var id = $('li:first').data('movieId');
// ==> id == 131
data() Storage
data attributes
•will try to use
correct data type
•parses JSON
values
map() Utility
projections for your
       arrays
map() Utility
  array-like: has
 most of what's
needed to be used
    as an array
    var arrayLike = {
       length: 2,
       0: 'first',
       1: 'second'
    };
map() Utility
   bonus utility:
   makeArray()
var arr = $.makeArray(arrayLike);
// ==> ['first','second']
map() Utility

var users = getUsersArray();

var emails =
  $.map(users, function(user, i){
      return user.profile.email;
  });
map() Utility

var users = getUsersArray();

var emails =
  $.map(users, function(user, i){
      return user.profile.email;
  });
map() Utility
    the callback
      function
•return new value
for the position
•return null to
exclude that position
re
Quick



                  ca
•




                    p
 end(): avoid
unnecessary
traversals
•computed
attributes
•relative CSS
attributes
Event
Handling
jQuery
determine which
 element and...
bind(), live(),
 delegate(),
well, yes - choices
bind() vs. live()
$('#container .action')
   .bind('click', function(){
       //do stuff here
   });
//same as: $('#container .action')
//      .click(function(){...});

//prefer:
$('#container .action')
   .live('click', function(){
       //do stuff here
   });
bind() vs. live()

•live(): more
efficient usage
•live(): works for
added elements
•live(): forces you
to deal with the
live() vs. delegate()

$('#container .action')
   .live('click', doStuff);

$('#container')
   .delegate('.action','click', doStuff);
live() vs. delegate()

 • live(): syntax is
  slightly easier
 • live(): attaches to
  document
 • delegate():
  attaches closer
Everything vs. on()
$('#close').bind('click', closeWindow);
$('#close').on('click', closeWindow);


$('.popup').delegate(
        '.closeBtn','click', closePopup);

$('.popup').on(
        'click','.closeBtn', closePopup);
Everything vs. on()
$('#close').bind('click', closeWindow);
$('#close').on('click', closeWindow);


$('.popup').delegate(
        '.closeBtn','click', closePopup);

$('.popup').on(
        'click','.closeBtn', closePopup);

                                            1.7
Custom
they remove tight
    coupling
Custom Events
$('#widget').on('start', function(){
    //do stuff
});

//elsewhere, maybe in another js file:
$('#widget').on('start', function(){
    //do other stuff
});

//when appropriate:
$('#widget').trigger('start');
Custom Events
$('#btn1').on('lock', function(){
    $(this).prop('disabled', true);
});

//elsewhere, maybe in another js file:
$('#toolbar').on('lock', function(){
    $(this).find('.icon').remove();
});

//when appropriate:
$.event.trigger('lock');
proxy()
let's put this in
     context
proxy() Utility

var f = $.proxy(obj, 'doSomething');

var f = $.proxy(obj.doSomething, obj);
re
Event



                 ca
•




                   p
 pick the right
binding command
•delegate() over
live()
•on() unifies it all
•decouple with
Extensio
   ns
Custom
the abc of jQuery
     mastery
Custom Commands
 function stripeTable(table, alt) {
   $(table)
       .find('tr:odd')
       .addClass(alt||'alternate');
 }
 //...
 var table = $('#mytable')[0];
 stripeTable(table, 'altRow');
Custom Commands
 jQuery.fn.stripe = function(alt) {
    this
       .children(':odd')
       .addClass(alt||'alternate');
     return this;
 };
 //...
 $('#mytable').stripe('altRow');
Custom Commands
 jQuery.fn.stripe = function(alt) {
    this
       .children(':odd')
       .addClass(alt||'alternate');
     return this;
 };
 //...
 $('#mytable').stripe('altRow');
Custom
expressive means
    readable
Custom

$.expr[':'].myfilter = function(el) {
   //return true if el(ement) matches
}
//...
$('div:myfilter').slideDown();
re
Extensions



                 ca
                   p
•commands
•expressions
•events
1.5




Deferred
 Object
Futures,
decouple the task
   from what
 you do with its
    outcome
Tidy Callbacks
startLongProcess(
   function(result){
      useResult(result);
      logCompletion(result);
   },
   function(error){
      logCompletion(result);
      logFailure(error);
   }
);
Tidy Callbacks
startLongProcess(
   function(result){
      useResult(result, function(res2){
          updateScreen(res2);
      });
      logCompletion(result);
   },
   //...
);
Tidy Callbacks
var task = startLongProcess()
  .done(useResult)
  .always(logCompletion)
  .fail(logFailure);

doSomethingElse();

//time passes...
task.fail(function(){
    alert('error');
});
Tidy Callbacks
var task = startLongProcess()
  .always(logCompletion)
  .fail(logFailure);

$.when(task, otherTask)
 .then(function(args1, args2){
      useResult(args1[0])
       .done(updateScreen);
  });
Deferreds in
 time to relearn
 some features
Ajax

var fetch = $.get('/data.aspx')
    .done(validateResponse)
    .done(doSomething)
    .done(doMoreStuff)
    .fail(reportError);

fetch.fail(resetUI);
when() Utility
$.when(
   $.get('/somedata'),
   $.get('/moredata'),
   $.post('/updatedata', data),
   someOtherDeferred)

 .then(function(){
       alert('all done');
   });
promise()
$('.widget')
   .first().fadeOut(500).end()
   .last().fadeOut(1000).end()
   .promise() //default: 'fx' queue
   .done(function(){
     //do something...
   });
re
Deferred



               ca
                 p
•common way for
callbacks
•returned by jQuery
Ajax
•for command
queues too
The True
 Source
github
     https://
github.com/jquery
github
     https://
github.com/jquery
Build It, Run
check out QUnit
Question
   s?
Reference

•http://
api.jquery.com
•Paul Irish's articles
and videos
Thank
 You

More Related Content

Advanced jQuery

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. for this talk I&apos;ll assume you all know the basics of jQuery and have been using it for DOM manipulation and Ajax calls. I&apos;ll show some of the other things in jq that could be labeled as intermediate to advanced. I&apos;ll try to highlight anything that is new in 1.7.\n
  5. for this talk I&apos;ll assume you all know the basics of jQuery and have been using it for DOM manipulation and Ajax calls. I&apos;ll show some of the other things in jq that could be labeled as intermediate to advanced. I&apos;ll try to highlight anything that is new in 1.7.\n
  6. I normally don&apos;t like presentations that are all about tricks and trips because it&apos;s hard to keep track of everything. I&apos;ll try to keep the machine gun quiet but I still wanted to highlight a handful of helpful gems in jq.\n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. DEMO!\n
  13. \n
  14. DEMO!\n
  15. \n
  16. \n
  17. \n
  18. DEMO!\n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. this should be familiar to most of you. The Select() Linq extension does that for IEnumerables in .net. We do the conversion with callback.\n
  28. this should be familiar to most of you. The Select() Linq extension does that for IEnumerables in .net. We do the conversion with callback.\n
  29. But there are a few things to note in the callback function.\n
  30. \n
  31. Event handling is one of the main reasons we use jquery for...\n
  32. It makes it so easy to watch for an event of an element... just choose the element and...\n
  33. Oh, that&apos;s that too. It&apos;s easy but it takes a little practice to pick the most efficient route. I&apos;m sure a few of us still has to think about it or look up docs to choose the right one for the task.\n
  34. both bind and live allow us to setup handlers for one or many elements in a single command. Select all the elements you want and attach the handler. main diff: dynamically added elements\n
  35. unique elements: elements that don&apos;t have a similar purpose with any other element on the page.\n
  36. OK, it was easy to figure out between the previous 2. But those two appear to do the same. Attach a handler for a selector.\nDiff: delegate() attaches a handler to the parent, not Doc. Syntax.\n
  37. \n
  38. on() can also take a data parameter that goes to event.data\n
  39. \n
  40. \n
  41. global events\n
  42. \n
  43. DEMO!\n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. DEMO!\n
  55. \n
  56. \n
  57. \n
  58. this is possible way to invoke a callback-based async function... note the two different callbacks, for success and error. note the duplication too.\n
  59. it could get worse. look what would happen if useResult was also async... what if an error happens in useResult? another error callback?\n
  60. see how much cleaner the code becomes when we introduce the deferred task object.\nWe can even subscribe later and it will fire immediately if the task has completed already. DEMO1!\n
  61. the tasks allow us to compose more complicated scenarios without sacrificing too much the read-ability of the code.\n
  62. \n
  63. \n
  64. DEMO2!\n
  65. Internally jQuery can maintain queues of actions. One such queue is the one that allows effects to execute sequentially.\nThe promise command returns a deferred task that resolves when the queue empties.\n
  66. \n
  67. \n
  68. \n
  69. show github, show how files are split, show local repo, build\n
  70. \n
  71. \n
  72. \n
  73. \n