jQuery
In with the new,
out with the old.
Agenda
๏ Understanding jQuery
๏ What's new & interesting
๏ Where you don't need it
Grokking
jQuery
DOM library
$('div').append(html).click(doStuff);
Just a CSS selector


$('div').append(html).click(doStuff);
$('div').append(html).click(doStuff);
$('div').append(html).click(doStuff);
if ( $('foo') ) {
  doAmazing();
}
1) $('foo')
2) $()
3) []
4) [].join(',') // works
if ( $('foo') ) {
  doAmazing();
}
if ( $('foo').length ) {
  doAmazing();
}
If your jQuery code fails,
and there's no error:

it's the selector
DOM Navigation
Find

Changes the collection
Filter

 Creates a subset
Debugging
New
Stuff
Ajax changes
  & Deferreds
$.get('foo.html', function (html) {
var jqXHR = $.get('foo.html');
  $('#latest').append(html);
});
jqXHR.done(function (html) {
  $('#latest').append(html);
});
$.ajax({
  url: 'foo.json',
  dataType: 'json',
  success: function () {
     // this === xhr
  },
  error: function () {

  }
});
$.ajax({
  url: 'foo.json',
  dataType: 'json',
  context: document.body,
  success: function () {
     // this === body element
  },
  error: function () {

  }
});
var jqXHR = $.ajax({
  url: 'foo.json',
  dataType: 'json',
  context: document.body
});

jqXHR.then(success, fail);
var jqXHR = $.ajax({
  url: 'foo.json',
  dataType: 'json',
  context: document.body
});

jqXHR.then(success, fail);

// much later in the code

jqXHR.done(success2);
jqXHR is a
promise
var jqXHR = $.ajax({
  url: 'foo.json',
  dataType: 'json',
  context: document.body
});

// much later in the code

jqXHR.done(success);
.done(ok)   // success
.fail(fail) // error
.always(fn) // complete
.then(ok, fail)
var dfd = $.Deferred();


    .resolve
    .reject
    .promise
var jqXHR = $.ajax({
  url: 'foo.json',
  dataType: 'json',
  context: document.body
});

// much later in the code

jqXHR.done(success);
function save(data) {
  var dfd = new $.Deferred();

    // some validation done...

    if (!valid) {
      dfd.reject(reason);
    } else {
      $.ajax({
        url: '/app/save',
        data: data,
        success: dfd.resolve,
        error: dfd.reject
      });
    }

    return dfd.promise();
}
nction save(data) {
var dfd = new $.Deferred();

// some validation done...

if (!valid) {             save({ /* some data */ })
  dfd.reject(reason);       .done(function () {
} else {                       // show it's all good
  $.ajax({
                            })
    url: '/app/save',
    data: data,             .fail(function (reason) {
    success: dfd.resolve,      // shows reason
    error: dfd.reject       });
  });
}

return dfd.promise();
$.when
$.when
var $boxes = $('div'),
    rand = Math.random,
    dfds = [];

for (var i = 0; i < 3; i++) {
  dfds.push($.Deferred());
  $boxes.eq(i).fadeTo(rand() * 5000, 1, dfds[i].resolve);
}

$.when.apply($, dfds).done(function () {
  alert('all done!');
});
$.sub()
(function ($) {
  $ = $.sub(); // sandbox $.fn

  $.fn.logger = function () {
    return this.each(function(){
      console.log(this)
    });
  }

  // my code that uses .logger()
})(jQuery);

// now: $.fn.logger === undefined
(function ($) {
  $ = $.sub(); // sandbox $.fn

  $.fn.logger = function () {
    return this.each(function(){
      console.log(this)
    });
  }

  // my code that uses .logger()
})(jQuery);

// now: $.fn.logger === undefined
Doing it
wrong
.ready?
...
<!-- all my funky markup -->
...
<script>
$(document).ready(function () {
  // add the extra funk
});
</script>
</body>
</html>
.ready?
...
<!-- all my funky markup -->
...
<script>

  // add the extra funk

</script>
</body>
</html>
Add class
...
<!-- all my funky markup -->
...
<script>

$('#foo').addClass('amazing');


</script>
</body>
</html>
Add class
...
<!-- all my funky markup -->
...
<script>

var f = document.getElementById('foo');
foo.className += ' amazing';

</script>
</body>
</html>
Effects vs. CSS
๏ Ifthe browser can do it
 natively, let it do it
 natively.
๏ Noone lost business because
 IE didn't do a cross fade.
return false
$('a').click(function () {
  // do the magic
  amazingMagic();

  return false;
});
return false

๏ Do you know what's happening?
๏ event.preventDefault()
๏ event.stopPropagation()
Get to know this
$('a').click(function (e) {
  e.preventDefault();

  var href = $(this).attr('href');
  // do the magic
  amazingMagic(href);
});
Get to know this
$('a').click(function (e) {
  e.preventDefault();

  var href = this.href;
  // do the magic
  amazingMagic(href);
});
Poorly designed plugins
$.fn.myplugin = function () {
  var me = $(this).each(function() {
    return $(this).bind('someEvent', function () {
      // does something
    });
  });

  return me;
};
$.fn.myplugin = function () {
  var me = $(this).each(fn);

  return me;
};
$.fn.myplugin = function () {
  return $(this).each(fn);
};
$.fn.myplugin = function () {
  return $(this).each(function() {
    return $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
  return $(this).each(function() {
    return $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
  return this.each(function() {
    return $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
  return this.each(function() {
    return $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
  return this.each(function() {
    $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
  return this.each(function() {
    $(this).bind('someEvent', function () {
      // does something
    });
  });
};
$.fn.myplugin = function () {
   return this.bind('someEvent', function () {
     // does something
  });
};
(function ($) {
  $.fn.myplugin = function () {
    return this.bind('someEvent', function () {
       // does something
     });
  };
})(jQuery);
Questions?
@rem
remy@leftlogic.com

jQuery: out with the old, in with the new

  • 1.
    jQuery In with thenew, out with the old.
  • 2.
    Agenda ๏ Understanding jQuery ๏What's new & interesting ๏ Where you don't need it
  • 3.
  • 4.
  • 5.
  • 6.
    Just a CSSselector $('div').append(html).click(doStuff);
  • 7.
  • 8.
  • 9.
    if ( $('foo')) { doAmazing(); }
  • 10.
    1) $('foo') 2) $() 3)[] 4) [].join(',') // works
  • 11.
    if ( $('foo')) { doAmazing(); }
  • 12.
    if ( $('foo').length) { doAmazing(); }
  • 13.
    If your jQuerycode fails, and there's no error: it's the selector
  • 14.
  • 15.
  • 16.
  • 17.
  • 19.
  • 20.
    Ajax changes & Deferreds
  • 21.
    $.get('foo.html', function (html){ var jqXHR = $.get('foo.html'); $('#latest').append(html); }); jqXHR.done(function (html) { $('#latest').append(html); });
  • 22.
    $.ajax({ url:'foo.json', dataType: 'json', success: function () { // this === xhr }, error: function () { } });
  • 23.
    $.ajax({ url:'foo.json', dataType: 'json', context: document.body, success: function () { // this === body element }, error: function () { } });
  • 24.
    var jqXHR =$.ajax({ url: 'foo.json', dataType: 'json', context: document.body }); jqXHR.then(success, fail);
  • 25.
    var jqXHR =$.ajax({ url: 'foo.json', dataType: 'json', context: document.body }); jqXHR.then(success, fail); // much later in the code jqXHR.done(success2);
  • 26.
  • 29.
    var jqXHR =$.ajax({ url: 'foo.json', dataType: 'json', context: document.body }); // much later in the code jqXHR.done(success);
  • 30.
    .done(ok) // success .fail(fail) // error .always(fn) // complete .then(ok, fail)
  • 31.
    var dfd =$.Deferred(); .resolve .reject .promise
  • 32.
    var jqXHR =$.ajax({ url: 'foo.json', dataType: 'json', context: document.body }); // much later in the code jqXHR.done(success);
  • 33.
    function save(data) { var dfd = new $.Deferred(); // some validation done... if (!valid) { dfd.reject(reason); } else { $.ajax({ url: '/app/save', data: data, success: dfd.resolve, error: dfd.reject }); } return dfd.promise(); }
  • 34.
    nction save(data) { vardfd = new $.Deferred(); // some validation done... if (!valid) { save({ /* some data */ }) dfd.reject(reason); .done(function () { } else { // show it's all good $.ajax({ }) url: '/app/save', data: data, .fail(function (reason) { success: dfd.resolve, // shows reason error: dfd.reject }); }); } return dfd.promise();
  • 35.
  • 36.
    $.when var $boxes =$('div'), rand = Math.random,     dfds = []; for (var i = 0; i < 3; i++) {   dfds.push($.Deferred());   $boxes.eq(i).fadeTo(rand() * 5000, 1, dfds[i].resolve); } $.when.apply($, dfds).done(function () {   alert('all done!'); });
  • 37.
  • 38.
    (function ($) { $ = $.sub(); // sandbox $.fn $.fn.logger = function () { return this.each(function(){ console.log(this) }); } // my code that uses .logger() })(jQuery); // now: $.fn.logger === undefined
  • 39.
    (function ($) { $ = $.sub(); // sandbox $.fn $.fn.logger = function () { return this.each(function(){ console.log(this) }); } // my code that uses .logger() })(jQuery); // now: $.fn.logger === undefined
  • 40.
  • 41.
    .ready? ... <!-- all myfunky markup --> ... <script> $(document).ready(function () { // add the extra funk }); </script> </body> </html>
  • 42.
    .ready? ... <!-- all myfunky markup --> ... <script> // add the extra funk </script> </body> </html>
  • 43.
    Add class ... <!-- allmy funky markup --> ... <script> $('#foo').addClass('amazing'); </script> </body> </html>
  • 44.
    Add class ... <!-- allmy funky markup --> ... <script> var f = document.getElementById('foo'); foo.className += ' amazing'; </script> </body> </html>
  • 45.
    Effects vs. CSS ๏Ifthe browser can do it natively, let it do it natively. ๏ Noone lost business because IE didn't do a cross fade.
  • 46.
    return false $('a').click(function (){ // do the magic amazingMagic(); return false; });
  • 47.
    return false ๏ Doyou know what's happening? ๏ event.preventDefault() ๏ event.stopPropagation()
  • 48.
    Get to knowthis $('a').click(function (e) { e.preventDefault(); var href = $(this).attr('href'); // do the magic amazingMagic(href); });
  • 49.
    Get to knowthis $('a').click(function (e) { e.preventDefault(); var href = this.href; // do the magic amazingMagic(href); });
  • 50.
  • 51.
    $.fn.myplugin = function() {   var me = $(this).each(function() {     return $(this).bind('someEvent', function () {       // does something     });   });   return me; };
  • 52.
    $.fn.myplugin = function() {   var me = $(this).each(fn);   return me; };
  • 53.
    $.fn.myplugin = function() {   return $(this).each(fn); };
  • 54.
    $.fn.myplugin = function() {   return $(this).each(function() {     return $(this).bind('someEvent', function () {       // does something     });   }); };
  • 55.
    $.fn.myplugin = function() {   return $(this).each(function() {     return $(this).bind('someEvent', function () {       // does something     });   }); };
  • 56.
    $.fn.myplugin = function() {   return this.each(function() {     return $(this).bind('someEvent', function () {       // does something     });   }); };
  • 57.
    $.fn.myplugin = function() {   return this.each(function() {     return $(this).bind('someEvent', function () {       // does something     });   }); };
  • 58.
    $.fn.myplugin = function() {   return this.each(function() {     $(this).bind('someEvent', function () {       // does something     });   }); };
  • 59.
    $.fn.myplugin = function() {   return this.each(function() {     $(this).bind('someEvent', function () {       // does something     });   }); };
  • 60.
    $.fn.myplugin = function() { return this.bind('someEvent', function () {   // does something   }); };
  • 61.
    (function ($) { $.fn.myplugin = function () {   return this.bind('someEvent', function () {     // does something   }); }; })(jQuery);
  • 62.