I know jQuery. Now what?

I know jQuery. Now what?

I've always been a big believer in using jQuery as a shortcut route to adding interactivity to web sites. You don't need to know the intricacies of browsers bugs around the DOM. But now you've got that essential jQuery knowledge, what's next? How do you live without jQuery? Are we even there yet? And what about your colleagues and peers - how do they progress with you?

C8b387c489181844b3ffc704fadc0f14?s=128

Remy Sharp

April 19, 2013
Tweet

Transcript

  1. I know jQuery. Now what? Remy Sharp • @rem

  2. 7 years ago...

  3. 7 years ago... Actually, me 7 years ago...

  4. $ =

  5. None
  6. None
  7. Ajax Grokage Ajax + me WAT?

  8. function getXmlHttpRequest() { var xhr; if (window.XMLHttpRequest) { xhr =

    new XMLHttpRequest(); } else { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xhr = false; } } } return xhr; } // disclaimer: John's jQuery version is a lot more elegant!
  9. Back to the Future

  10. querySelectorAll

  11. var $ = document.querySelectorAll.bind(document); Element.prototype.on = Element.prototype.addEventListener; $('#somelink')[0].on('touchstart', handleTouch);

  12. None
  13. When I use jQuery

  14. No mustard cu ing: I include jQuery.

  15. if (querySelector in document && localStorage in window && addEventListener

    in window) { // bootstrap the JavaScript app }
  16. Quick 'n Dirty

  17. Sans jQuery

  18. document.ready

  19. .attr()

  20. $('input').on('change', function () { var value = $(this).attr('value'); alert('The new

    value is' + value); });
  21. $('input').on('change', function () { var value = this.value; alert('The new

    value is' + value); });
  22. $('a').attr('href') a.getAttribute('href') a.href

  23. <script src="jquery.min.js"></script> </head> <body> <script> $('body').addClass('hasJS'); </script>

  24. </head> <body> <script> document.body.className = 'hasJS'; </script>

  25. Classy

  26. body.className += ' hasJS'

  27. body.classList.add('hasJS')

  28. body.classList.remove('hasJS')

  29. body.classList.toggle('hasJS')

  30. body.classList.add('foo', 'bar')

  31. body.classList.contains(''); // SyntaxError: DOM Exception 12 :(

  32. data

  33. el.dataset.user = JSON.stringify(user); el.dataset.score = score;

  34. ax

  35. function request(type, url, opts, callback) { var xhr = new

    XMLHttpRequest(); if (typeof opts === 'function') { callback = opts; opts = null; } xhr.open(type, url); // serialise post data if (type === 'POST' && opts) { // <snip...so I can make the slide smaller> } xhr.onload = function () { callback(JSON.parse(xhr.response)); }; xhr.send(opts ? fd : null); } var get = request.bind(this, 'GET'); var post = request.bind(this, 'POST');
  36. function request(type, url, opts, callback) { var xhr = new

    XMLHttpRequest(); if (typeof opts === 'function') { callback = opts; opts = null; } xhr.open(type, url); // serialise post data if (type === 'POST' && opts) { // <snip...so I can make the slide smaller> } xhr.onload = function () { callback(JSON.parse(xhr.response)); }; xhr.send(opts ? fd : null); } var get = request.bind(this, 'GET'); var post = request.bind(this, 'POST'); xhr.onload = function () { callback(JSON.parse(xhr.response)); };
  37. function request(type, url, opts, callback) { var xhr = new

    XMLHttpRequest(); if (typeof opts === 'function') { callback = opts; opts = null; } xhr.open(type, url); // serialise post data if (type === 'POST' && opts) { // <snip...so I can make the slide smaller> } xhr.onload = function () { callback(JSON.parse(xhr.response)); }; xhr.send(opts ? fd : null); } var get = request.bind(this, 'GET'); var post = request.bind(this, 'POST');
  38. •CORS •Progress events •Upload progress events •Different posting types •Using

    FormData
  39. fffffffffforms!

  40. <input type="email">

  41. <input type="email" required>

  42. <input pattern="[a-z0-9]">

  43. Style & animation

  44. CSS > JS

  45. CSS > JS

  46. CSS > JS (for CSS, duh)

  47. Ss

  48. Bad: .css

  49. Good: .addClass

  50. Gooderer: .className

  51. If it's native to the browser, let the browser get

    on with it's job.
  52. Animation

  53. setInterval VS. requestAnimationFrame

  54. setInterval requestAnimationFrame

  55. None
  56. rAF > setInterval

  57. CSS animations also uses rAF scheduling

  58. None
  59. Translate =

  60. el.on("webkitTransitionEnd", ended); el.on("transitionend", ended); Note the the lowercase 'e' on

    'end'...
  61. And yes, there are plugins. 1. jQuery-Animate-Enhanced 2. jQuery.Transit

  62. jQuery plugin. Just because.

  63. None
  64. None
  65. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); };
  66. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); }; 1. extend
  67. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); }; 1. extend 2. each
  68. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); }; 1. extend 2. each 3. width
  69. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); }; 1. extend 2. each 3. width 4. css
  70. $.fn.fitText = function( kompressor, options ) { // Setup options

    var compressor = kompressor || 1, settings = $.extend({ 'minFontSize' : Number.NEGATIVE_INFINITY, 'maxFontSize' : Number.POSITIVE_INFINITY }, options); return this.each(function(){ // Store the object var $this = $(this); // Resizer() resizes items based on the object width divided by the compressor * 10 var resizer = function () { $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize))); }; // Call once to set. resizer(); // Call on resize. Opera debounces their resize by default. $(window).on('resize orientationchange', resizer); }); }; 1. extend 2. each 3. width 4. css 5. on
  71. if (options === undefined) { options = {}; } if

    (options.minFontSize === undefined) { options.minFontSize = Number.NEGATIVE_INFINITY; } if (options.maxFontSize === undefined) { options.maxFontSize = Number.POSITIVE_INFINITY; } .extend becomes init default options
  72. // assuming polyfill or IE9+ nodes.forEach(function (node) { // where

    we used `this`, we now use `node` // ... }) .each becomes regular loop
  73. var resizer = function () { var width = node.clientWidth;

    // ... }; .width becomes .clientWidth property Note: clientWidth != .width() - but will do for our solution
  74. node.style.fontSize = Math.max(...); .css becomes se ing style property

  75. // assuming polyfill or IE9+ window.addEventListener('resize', resizer, false); .on becomes

    .addEventLister Polyfill: h ps://gist.github.com/eirikbacker/2864711
  76. Idea: Why not use PE to support jQuery?

  77. Recap querySelectorAll for DOM navigation Think about when to use

    jQuery / a library Ditch document.ready Use this.value Try .classList Really grok ajax No more JavaScript animations Maybe no-jQuery first?
  78. Your turn.