jQuery Features to Avoid
                          Dave Methvin
          President, jQuery Foundation
                jQuery Core Team Lead
jQuery Is Evolving
● There are things in jQuery that ...
  ○ make code fragile in large projects
  ○ make code hard to understand
  ○ make code SLOW
● ... so you should avoid them!

But how did this happen?
The World of jQuery 1.0
The World of jQuery 1.0
● January 2006 browser market share
  76% Internet Explorer 5.5 and 6.0
  13% Firefox 1.x
  11% Others (Netscape, AOL)
● State of web development in 2006
  ○   HTML4, EcmaScript 3 (IE5 lacked try-catch)
  ○   AJAX term just coined in February 2005
  ○   Nearly all pages were full-reload design
  ○   JavaScript was generally non-essential
It's Gotten Complicated
●   Single page applications -- LEAKS!
●   Massive amounts of JavaScript
●   Script breaks? Page doesn't work.
●   MORE browsers and screen sizes!
    ○ IE6-10, Firefox 3.6-15, Chrome 20-22, Safari
      3-6, plus mobile browser variants (Android,
      iPhone/iPod, BlackBerry) which are often
      old and never updated! Bonus: IE9 on Xbox!
What Most Devs Want From jQuery
Temptation to         over   Simplify
Wouldn't it be cool if jQuery...
● ...automagically figured out what kind of
  AJAX/JSONP request to make and did the
  "right thing" with the response?
● It's wonderful when it works
● Hard to debug when it doesn't
● Crazy hard to document
Complex APIs Make You Grumpy
jQuery Adapts
● Version 1.9 will remove some features
  ○ There is a compat plugin (cough, crutch)
● Version 2.0 removes support for IE 6/7/8
● We will maintain both 1.9 and 2.0 and
  the APIs will be compatible
    Result?
       ● Smaller size
       ● Better performance
       ● Fewer "trip hazards"
Avoid Deprecated Things!
● http://api.jquery.com/category/deprecated/
● Ineffective, Inefficient, Inadvisable ...
$.browser
● Sniffs around navigator.userAgent string
● Easily fooled and fragile
● Not future-proof -- bug in this version of
  Chrome or IE is no guarantee of bug in
  future Chrome or IE!
● Usually you want to feature detect
● Modernizr!
.toggle(fn1, fn2, fn3 ...)
● Cool method, bro
● Not really "core" functionality
● Lots of caveats in the docs
  ○ http://api.jquery.com/toggle-event/
  ○ "Practically reads like a suicide note"
jQuery is not JavaScript!
jQuery is not JavaScript!
jQuery is not JavaScript!
Avoid using jQuery...
● ...when JavaScript or W3C APIs are
  more appropriate and performant
● Remember: jQuery is a DOM library
● All of JavaScript is yours to command
● jQuery tries to avoid getting in your way
Typical Checkbox Handler
$("#sameAsBillTo").on("click",
   function(){
     if ( $(this).is(":checked") ) {
       $("#shipTo").hide();
     } else {
       $("#shipTo").show();
     }
   }
);
Use this, not $(this)
Instead of $(this) …      Use this!
$(this).is(“:checked”)    this.checked
$(this).prop(“checked”)   this.checked
$(this).is(“:disabled”)   this.disabled
$(this).attr(“id”)        this.id
$(this).attr(“class”)     this.className
Use this, not $(this)
Instead of $(this) …      Use this!
$(this).is(“:checked”)    this.checked
$(this).prop(“checked”)   this.checked
$(this).is(“:disabled”)   this.disabled
$(this).attr(“id”)        this.id
$(this).attr(“class”)     this.className


    Up to 100 times faster!
Better Checkbox Handler

$("#sameAsBillTo").on("click",
 function(){
   $("#shipTo").toggle(!this.checked);
 }
);
Use W3C CSS Selectors
Selector extension     Use this (W3C CSS)
:checkbox, :radio, :   input[type=X]
text, :image, :file, :
reset

:button                button, input[type=button]

:header                h1, h2, h3, h4, h5

:first                 :first-child or .first()

:last                  :last-child or .last()
Even More Stuff To Avoid...
●   Features we can't remove
●   Too frequently and commonly used
●   Sometimes cute, but they'll bite you
●   Especially bad on large projects
How Every Project Starts
What Every Project Becomes
$(html, props)
● You can say:
  $("<p />")
     .attr("class", "active")
     .click(myClickHandler)
     .text("Hello world")
     .appendTo("body");

● Or, using $(html, props):
  $("<p />", {
     "class": "active",
     click: myClickHandler,
     text: "Hello world"
  }).appendTo("body");
$(html, props) Pitfalls 1
● If the name is a method, it's called with
  the (single) argument you provide:
  $("<input />", {
    type: "checkbox",
    prop: { checked: true }
  }).appendTo("body");

● No method with that name? It will be set
  as an attribute!
$(html, props) Pitfalls 2
● Methods can collide with attributes!
  $("<input />", {
    type: "text",
    size: "15" // uh-oh! $.fn.size()
    attr: { size: 15 } // works
  }).appendTo("body");

● This can happen with plugins someone
  adds to the project at a later time
Action at a Distance
jQuery.ajaxOptions()
● Lets you change behavior of $.ajax()

● GLOBALLY
● Including any third-party plugins
● Most jQuery code expects the "normal"
  defaults that are documented by the API
What does this do?
   $.ajax({
     url: "file.txt",
     success: function(data){
       alert(data);
     }
   });
How I Hosed Your AJAX
  $.ajaxSetup({
    type: "POST",
    dataType: "json",
    timeout: 500 // ms!
  });
Avoiding Ajax Annihilation
Make your own $.ajax() wrapper:
  function jsonRequest(options)
  {
    return $.ajax(
       $.extend({
          dataType: "json",
          ...
       }, options)
    );
  }
Using $() to create HTML
● jQuery(), aka $(), accepts anything!
  ○   function (for document ready)
  ○   DOM element
  ○   Array of DOM elements
  ○   A plain JavaScript object
  ○   HTML element string and props (as we saw)
  ○   Arbitrary HTML string
  ○   Selector string and context
Using $() to create HTML
● jQuery(), aka $(), accepts anything!
  ○   function (for document ready)
  ○   DOM element
  ○   Array of DOM elements
  ○   A plain JavaScript object
  ○   HTML element string and props (as we saw)
  ○   Arbitrary HTML string
  ○   Selector string and context
The "Looks Like HTML" Rule
The "Looks Like HTML" Rule
"If a string is passed as the parameter to
$(), jQuery examines the string to see if it
looks like HTML (i.e., it has <tag...>
somewhere within the string). If not, the
string is interpreted as a selector
expression ..."

  -- http://api.jquery.com/jQuery/#jQuery2
Some people, when confronted
with a problem, think "I know,
I'll use regular expressions."
Now they have two problems.

            -- Jamie Zawinski
Cross site scripting (XSS)
● $() can run <script>s in HTML
● $() can set HTML inline event handlers
● Many sites use unvalidated input to $()
  ○ "http://mysite.com/page.html#someid"
  ○ $(window.location.hash) // #someid
  ○ Uh oh!
     ■ http://jsfiddle.net/dmethvin/uKYUP/
Rule Change for jQuery 1.9
● A string will only "look like HTML" if it
  starts with a "<" character!
● Leading whitespace allowed? Maybe.
● Helps to prevent inadvertent script
  interpretation in HTML
● Developers still must validate input!
Selector or HTML in 1.7?
1)   "<p>Hello</p>" HTML
2)   "Hello<p>there</p> world!" HTML
3)   ".tip[title='Hello']" selector
4)   ".tip[title='<b>Hello</b>']" HTML
5)   "#footer .copyright" selector
6)   "#ONE <b>Redskins</b> fan!" HTML
Selector or HTML in 1.9?
1)    "<p>Hello</p>" HTML
2)    "Hello<p>there</p> world!" selector
3)    ".tip[title='Hello']" selector
4)    ".tip[title='<b>Hello</b>']" selector
5)    "#footer .copyright" selector
6)    "#ONE <b>Redskins</b> fan!" selector
     Note that many of these are NOT valid
     CSS selectors and will throw an error.
Say what you want!
● In jQuery 1.8:
  ○ $.parseHTML(html, runScripts)
     ■ html is a string of arbitrary HTML
     ■ runScripts is a Boolean that says whether to
       run inline or external scripts in the HTML;
       defaults to false.
● Not a panacea for all XSS problems
  ○ http://jsfiddle.net/dmethvin/VNBDF/
● Needs documentation...sorry!
jQuery's Not Perfect
●   Use the good parts
●   Avoid the bad parts
●   You'll be happier with jQuery
●   Your co-workers will thank you!
    You can find this presentation at:

    http://slideshare.net/
Questions?
 Twitter:
  @davemethvin

 Github:
  dmethvin

 IRC #jquery-dev:
   DaveMethvin

jQuery Features to Avoid

  • 1.
    jQuery Features toAvoid Dave Methvin President, jQuery Foundation jQuery Core Team Lead
  • 2.
    jQuery Is Evolving ●There are things in jQuery that ... ○ make code fragile in large projects ○ make code hard to understand ○ make code SLOW ● ... so you should avoid them! But how did this happen?
  • 3.
    The World ofjQuery 1.0
  • 4.
    The World ofjQuery 1.0 ● January 2006 browser market share 76% Internet Explorer 5.5 and 6.0 13% Firefox 1.x 11% Others (Netscape, AOL) ● State of web development in 2006 ○ HTML4, EcmaScript 3 (IE5 lacked try-catch) ○ AJAX term just coined in February 2005 ○ Nearly all pages were full-reload design ○ JavaScript was generally non-essential
  • 6.
    It's Gotten Complicated ● Single page applications -- LEAKS! ● Massive amounts of JavaScript ● Script breaks? Page doesn't work. ● MORE browsers and screen sizes! ○ IE6-10, Firefox 3.6-15, Chrome 20-22, Safari 3-6, plus mobile browser variants (Android, iPhone/iPod, BlackBerry) which are often old and never updated! Bonus: IE9 on Xbox!
  • 7.
    What Most DevsWant From jQuery
  • 8.
    Temptation to over Simplify Wouldn't it be cool if jQuery... ● ...automagically figured out what kind of AJAX/JSONP request to make and did the "right thing" with the response? ● It's wonderful when it works ● Hard to debug when it doesn't ● Crazy hard to document
  • 9.
  • 10.
    jQuery Adapts ● Version1.9 will remove some features ○ There is a compat plugin (cough, crutch) ● Version 2.0 removes support for IE 6/7/8 ● We will maintain both 1.9 and 2.0 and the APIs will be compatible Result? ● Smaller size ● Better performance ● Fewer "trip hazards"
  • 11.
    Avoid Deprecated Things! ●http://api.jquery.com/category/deprecated/ ● Ineffective, Inefficient, Inadvisable ...
  • 12.
    $.browser ● Sniffs aroundnavigator.userAgent string ● Easily fooled and fragile ● Not future-proof -- bug in this version of Chrome or IE is no guarantee of bug in future Chrome or IE! ● Usually you want to feature detect ● Modernizr!
  • 13.
    .toggle(fn1, fn2, fn3...) ● Cool method, bro ● Not really "core" functionality ● Lots of caveats in the docs ○ http://api.jquery.com/toggle-event/ ○ "Practically reads like a suicide note"
  • 14.
    jQuery is notJavaScript!
  • 15.
    jQuery is notJavaScript!
  • 16.
    jQuery is notJavaScript!
  • 17.
    Avoid using jQuery... ●...when JavaScript or W3C APIs are more appropriate and performant ● Remember: jQuery is a DOM library ● All of JavaScript is yours to command ● jQuery tries to avoid getting in your way
  • 18.
    Typical Checkbox Handler $("#sameAsBillTo").on("click", function(){ if ( $(this).is(":checked") ) { $("#shipTo").hide(); } else { $("#shipTo").show(); } } );
  • 19.
    Use this, not$(this) Instead of $(this) … Use this! $(this).is(“:checked”) this.checked $(this).prop(“checked”) this.checked $(this).is(“:disabled”) this.disabled $(this).attr(“id”) this.id $(this).attr(“class”) this.className
  • 20.
    Use this, not$(this) Instead of $(this) … Use this! $(this).is(“:checked”) this.checked $(this).prop(“checked”) this.checked $(this).is(“:disabled”) this.disabled $(this).attr(“id”) this.id $(this).attr(“class”) this.className Up to 100 times faster!
  • 21.
    Better Checkbox Handler $("#sameAsBillTo").on("click", function(){ $("#shipTo").toggle(!this.checked); } );
  • 22.
    Use W3C CSSSelectors Selector extension Use this (W3C CSS) :checkbox, :radio, : input[type=X] text, :image, :file, : reset :button button, input[type=button] :header h1, h2, h3, h4, h5 :first :first-child or .first() :last :last-child or .last()
  • 24.
    Even More StuffTo Avoid... ● Features we can't remove ● Too frequently and commonly used ● Sometimes cute, but they'll bite you ● Especially bad on large projects
  • 25.
  • 26.
  • 27.
    $(html, props) ● Youcan say: $("<p />") .attr("class", "active") .click(myClickHandler) .text("Hello world") .appendTo("body"); ● Or, using $(html, props): $("<p />", { "class": "active", click: myClickHandler, text: "Hello world" }).appendTo("body");
  • 28.
    $(html, props) Pitfalls1 ● If the name is a method, it's called with the (single) argument you provide: $("<input />", { type: "checkbox", prop: { checked: true } }).appendTo("body"); ● No method with that name? It will be set as an attribute!
  • 29.
    $(html, props) Pitfalls2 ● Methods can collide with attributes! $("<input />", { type: "text", size: "15" // uh-oh! $.fn.size() attr: { size: 15 } // works }).appendTo("body"); ● This can happen with plugins someone adds to the project at a later time
  • 30.
    Action at aDistance
  • 31.
    jQuery.ajaxOptions() ● Lets youchange behavior of $.ajax() ● GLOBALLY ● Including any third-party plugins ● Most jQuery code expects the "normal" defaults that are documented by the API
  • 32.
    What does thisdo? $.ajax({ url: "file.txt", success: function(data){ alert(data); } });
  • 33.
    How I HosedYour AJAX $.ajaxSetup({ type: "POST", dataType: "json", timeout: 500 // ms! });
  • 34.
    Avoiding Ajax Annihilation Makeyour own $.ajax() wrapper: function jsonRequest(options) { return $.ajax( $.extend({ dataType: "json", ... }, options) ); }
  • 35.
    Using $() tocreate HTML ● jQuery(), aka $(), accepts anything! ○ function (for document ready) ○ DOM element ○ Array of DOM elements ○ A plain JavaScript object ○ HTML element string and props (as we saw) ○ Arbitrary HTML string ○ Selector string and context
  • 36.
    Using $() tocreate HTML ● jQuery(), aka $(), accepts anything! ○ function (for document ready) ○ DOM element ○ Array of DOM elements ○ A plain JavaScript object ○ HTML element string and props (as we saw) ○ Arbitrary HTML string ○ Selector string and context
  • 37.
    The "Looks LikeHTML" Rule
  • 38.
    The "Looks LikeHTML" Rule "If a string is passed as the parameter to $(), jQuery examines the string to see if it looks like HTML (i.e., it has <tag...> somewhere within the string). If not, the string is interpreted as a selector expression ..." -- http://api.jquery.com/jQuery/#jQuery2
  • 39.
    Some people, whenconfronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. -- Jamie Zawinski
  • 40.
    Cross site scripting(XSS) ● $() can run <script>s in HTML ● $() can set HTML inline event handlers ● Many sites use unvalidated input to $() ○ "http://mysite.com/page.html#someid" ○ $(window.location.hash) // #someid ○ Uh oh! ■ http://jsfiddle.net/dmethvin/uKYUP/
  • 41.
    Rule Change forjQuery 1.9 ● A string will only "look like HTML" if it starts with a "<" character! ● Leading whitespace allowed? Maybe. ● Helps to prevent inadvertent script interpretation in HTML ● Developers still must validate input!
  • 42.
    Selector or HTMLin 1.7? 1) "<p>Hello</p>" HTML 2) "Hello<p>there</p> world!" HTML 3) ".tip[title='Hello']" selector 4) ".tip[title='<b>Hello</b>']" HTML 5) "#footer .copyright" selector 6) "#ONE <b>Redskins</b> fan!" HTML
  • 43.
    Selector or HTMLin 1.9? 1) "<p>Hello</p>" HTML 2) "Hello<p>there</p> world!" selector 3) ".tip[title='Hello']" selector 4) ".tip[title='<b>Hello</b>']" selector 5) "#footer .copyright" selector 6) "#ONE <b>Redskins</b> fan!" selector Note that many of these are NOT valid CSS selectors and will throw an error.
  • 44.
    Say what youwant! ● In jQuery 1.8: ○ $.parseHTML(html, runScripts) ■ html is a string of arbitrary HTML ■ runScripts is a Boolean that says whether to run inline or external scripts in the HTML; defaults to false. ● Not a panacea for all XSS problems ○ http://jsfiddle.net/dmethvin/VNBDF/ ● Needs documentation...sorry!
  • 45.
    jQuery's Not Perfect ● Use the good parts ● Avoid the bad parts ● You'll be happier with jQuery ● Your co-workers will thank you! You can find this presentation at: http://slideshare.net/
  • 46.
    Questions? Twitter: @davemethvin Github: dmethvin IRC #jquery-dev: DaveMethvin