KEMBAR78
Yearning jQuery | PDF
Yearning jQuery
Hi, I’m Remy / @rem

Screencast @
jqueryfordesigners.com

Questions: interrupt me
& ask!
1. Build without jQuery.

2. Design the start and end of your
  effects without jQuery.

3. Add jQuery a little at a time.
(a lot of it is...)


        "all about CSS"

                      Me, to many a colleague
@rem
     Remy Sharp



Dear designer/dev: if you're using
JavaScript to do a job that CSS could have
done perfectly well, you've lost some
points in my book. Sorry
@rem
     Remy Sharp



The day someone loses business because
an animated transition wasn't used to
reveal a screenshot: I'll sell my left nut on
eBay. #cssinstead
What we're covering

• Getting friendly with the $
• DOM navigation & manipulation
• Events
• Ajax
• Tips
APIs         Blogs, tutorials, screencasts,
 docs.jquery.com
                    plugins, development sprints
  api.jquery.com
 visualjquery.com



  Twitter                         forum.jquery.com
  @jquery           Help!
@jquerysites
 @jqueryui
                    IRC channel
             irc.freenode.net/#jquery
jsbin.com
Bling Function
It means no more of this
var tables = document.getElementsByTagName('table');
for (var t = 0; t < tables.length; t++) {
!   var rows = tables[t].getElementsByTagName('tr');
!   for (var i = 1; i < rows.length; i += 2) {
        if (!/(^|s)odd(s|$)/.test(rows[i].className)) {
            rows[i].className += ' odd';
        }
    }
}
jQuery simplifies


$('table tr:nth-child(odd)').addClass('odd');
jQuery simplifies

jQuery function

$('table tr:nth-child(odd)').addClass('odd');
jQuery simplifies

jQuery function

$('table tr:nth-child(odd)').addClass('odd');


             CSS expression
jQuery simplifies

jQuery function            jQuery method

$('table tr:nth-child(odd)').addClass('odd');


             CSS expression
jQuery simplifies


$('table tr:nth-child(odd)').addClass('odd');
$('just css')
Tools of the Trade
• Firefox: Firebug (& FireQuery*)
• Safari & Chrome: Web Inspector
• Opera: DragonFly
• IE: Web Developer Toolbar
Tip

      $.fn.jquery

        (little 'q')
Let's play.

http://twitter.com
jQuery on every site?
        No Problem.
http://bit.ly/9JAcCj
Let's play.
Installing jQuery
dev or min?
Hosting options
  • Host it yourself (good for offline
    dev)

  • Hotlink it:
   • Media Temple
   • Microsoft
   • Google (my pick)
http://docs.jquery.com/Downloading_jQuery
CDN FTW
Tip: keep a copy on
  your machine
Where does it all go?
• jQuery first
• Then jQuery plugins
• Then your code
• Other JavaScript libraries
• jQuery last library
• Then jQuery plugin scripts
• Then your code
<html>
<head>
  <styles>
  <!-- make me beautiful -->
  </styles>
</head>
<body>
  <content>
  <!-- make me learned -->
  </content>
  <behaviour>
  <!-- ooo, matron -->
  </behaviour>
</body>
</html>
<html>
                 <head>
                   <styles>
 Styles first      <!-- make me beautiful -->
let's the page     </styles>
                 </head>
   render
                 <body>
  without          <content>
   scripts         <!-- make me learned -->
                   </content>
  blocking
                   <behaviour>
                   <!-- ooo, matron -->
                   </behaviour>
                 </body>
                 </html>
<html>
                 <head>
                   <styles>
                   <!-- make me beautiful -->
 Then your         </styles>
  content,       </head>
again so that    <body>
                   <content>
it's delivered
                   <!-- make me learned -->
   to your         </content>
 visitor as        <behaviour>
                   <!-- ooo, matron -->
  early as
                   </behaviour>
  possible       </body>
                 </html>
<html>
               <head>
                 <styles>
                 <!-- make me beautiful -->
                 </styles>
               </head>
               <body>
Finally, add
                 <content>
   your          <!-- make me learned -->
behaviour,       </content>
the jQuery       <behaviour>
                 <!-- ooo, matron -->
 and sexy
                 </behaviour>
magic jazz.    </body>
               </html>
$(document).ready(function () {

      // < YOU >

});
$(document).ready(function () {

      // < YOU >

});
$(function () {

      // < YOU >

});
Tip
jQuery(function ($) {

      // < YOU >

});

       Useful when giving code to a client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 />
<title>My first jQuery page</title>
</head>
<body>
<h1>Remy woz 'ere</h1>
<p>Lorem ipsum dolor sit amet.</p>
<script src="jquery.min.js"></script>
<script>
$(function () {
    // < YOU >
});
</script>
</body>
</html>
Is it jQuery or $?
It's both.
$('table tr:nth-child(odd)')
jQuery('table tr:nth-child(odd)')
$('table tr:nth-child(odd)')
∞∞∞ Chaining ∞∞∞
$('div').show().hide().slideUp().slideDown();
$('div').show().hide().slideUp().slideDown();



            Get the divs,
$('div').show().hide().slideUp().slideDown();



          and show them,
$('div').show().hide().slideUp().slideDown();



          now hide them,
$('div').show().hide().slideUp().slideDown();



    and then slide them up,
$('div').show().hide().slideUp().slideDown();



then finally slide them down.
Can't chain text getters




.val() .html() .text() .css(prop) .attr(prop), etc
Gotc ha
  & Tip

  if ( $('foo') ) {
    doAmazing();
  }
1) $('foo')
2) $()
3) []
4) [].join(',') // works
if ( $('foo') ) {
  doAmazing();
}
if ( $('foo').length ) {
  doAmazing();
}
$('el').doStuff
        vs
  $.doStuff
$('el').doStuff
 runs against
  everything
   matched.
$.doStuff
is a utility.
Deprecated

$.browser.version
$.browser.msie
$.browser.safari
$.browser.webkit
Doing stuff
$('a').click(function () {
  alert('I got clicked');
  return false;
});
$('a').click(function () {
  alert('I got clicked');
  return false;
});


      Find the anchors
$('a').click(function () {
  alert('I got clicked');
  return false;
});


    when they're clicked
$('a').click(function () {
  alert('I got clicked');
  return false;
});

run this function - don't worry
   about the crazy syntax.
$('a').click(function () {
  alert('I got clicked');
  return false;
});

 Cancel the browser's default
 action, which is to redirect.
$('a').click(function(event){
   event.preventDefault();
   alert('I got clicked');
 });

Same thing as cancelling (almost),
  this is useful for debugging.
• click, dblclick
• mousedown, mouseup, mousemove
  mouseover, mouseout, mouseenter
  mouseleave

• keydown, keypress, keyup
• submit, change, blur, focus, select
• scroll, resize, load, error
Tabs freakin' everywhere!
You get the idea.
A tabbing system is...

• A group of "panels"
• Tabs (or links) pointing to a panel
• Clicking tab, hides all panels, then
  shows just one
...the content can
 also be be Ajaxy
A few words on this
this is the element
that the event is
happening to.
$('a').click(function () {
  console.log(this);
});


this is the anchor element, not the jQuery
wrapped element.
Common mistake
$('a').click(function () {
  setTimeout(function () {
    $(this).text("I'm alive!");
  }, 1000);
});
Common mistake
$('a').click(function () {
  setTimeout(function () {
    $(this).text("I'm alive!");
  }, 1000);
});


this is the window object, not the link
Common mistake
$('a').click(function () {
  var el = this;
  setTimeout(function () {
    $(el).text("I'm alive!");
  }, 1000);
});
Live codin' time!

     tabs.html
Events
$('input').keydown(function (event) {
  // what's the event arg?
});
•.keyup(fn), .click(fn), etc
•.bind(type, fn)
•.trigger(type), unbind(type)
•.one(type, fn)
Tip

      Clickables
$.event.special.click = {
   setup: function() {
      $(this).css('cursor','pointer');
      return false;
   },
   teardown: function() {
      $(this).css('cursor','');
      return false;
   }
};

                 All credit to David Walsh
Problem
<h1>Super Ted</h1>
               <img src="superted.jpg">
 When the
               <img src="spotty.jpg">
 page has      <img src="txspete.jpg">
 finished      <script src="jquery.js">
               <script>
loading, the
               $('img').click(function(){
jQuery runs      showDetails(this);
               });
               </script>
<h1>Super Ted</h1>
  Clicking     <img src="superted.jpg">
               <img src="spotty.jpg">
these images
               <img src="txspete.jpg">
  "shows       <script src="jquery.js">
  details"     <script>
               $('img').click(function(){
                 showDetails(this);
               });
               </script>
<h1>Super Ted</h1>
                <img src="superted.jpg">
 Now Ajax       <img src="spotty.jpg">
(or something   <img src="txspete.jpg">
else) add new   <script src="jquery.js">
                <script>
images to the   $('img').click(function(){
    page          showDetails(this);
                });
                </script>
<h1>Super Ted</h1>
                <img src="superted.jpg">
 Now Ajax       <img src="spotty.jpg">
                <img src="txspete.jpg">
(or something
                <img src="mothernature.jpg">
else) add new   <script src="jquery.js">
images to the   <script>
                $('img').click(function(){
    page
                  showDetails(this);
                });
                </script>
<h1>Super Ted</h1>
                <img src="superted.jpg">
                <img src="spotty.jpg">
Clicking this   <img src="txspete.jpg">
image doesn't   <img src="mothernature.jpg">
do anything.    <script src="jquery.js">
                <script>
                $('img').click(function(){
                  showDetails(this);
                });
                </script>
Solution: delegation
<h1>Super Ted</h1>
<img src="superted.jpg">
<img src="spotty.jpg">
<img src="txspete.jpg">
<script src="jquery.js">
<script>
$('#superTed').delegate('img','click',function(){
  showDetails(this);
});
</script>
These images
are loaded after
 the DOM has
loaded via Ajax
We're going to "delegate" the
task of listening for particular
     events to this <div>
We've "delegate" clicks,
looking for the "img" selector
$('div').delegate('img','click',function(){
  /* do funky stuff */
});
Now, any new images inserted in this
<div> can be clicked and will fire the
       "funky stuff" function
Ajax   Warning: wear your tech-hat
No brainer Ajax
.load
Example
$('#detail').load('page.html');
$('#detail').load('page.html #id');
1. Ajax load the page

2. Search for the selector passed
  (#dizzy)

3. Squirt contents found into original
  selector
$('#tabs a').click(function (event) {
  // this.pathname = 'ajax-load-detail.html'
  $('#detail').load(this.pathname);
  return false;
});
this.hash

$('#tabs a').click(function (event) {
  $('#detail').load(this.pathname + ' ' +
this.hash);
  return false;
});
JSON
JavaScript Object
{
    screen_name : "@rem",
    height : "short",
    fingers : 5,
    brit : true
}
JSON
{
    "screen_name": "@rem",
    "height": "short",
    "fingers": 5,
    "brit": true
}
JSONP WTF
JSON+...
{
    "screen_name": "@rem",
    "height": "short",
    "fingers": 5,
    "brit": true
}
JSON+Padding
callback({
 "screen_name": "@rem",
 "height": "short",
 "fingers": 5,
 "brit": true
});
Getting other
people's data
$.getJSON
Remember =?
Twitter
ajax/twitter.html
$(document).ready(function () {
  $.getJSON('http://twitter.com/statuses/user_timeline/rem.json?callback=?',
  function (data) {
    $('#tweets').empty();

    $.each(data, function (i, item) {
      $('#tweets').append('<li class="tweet">' + item.text + '</li>');
    });
  });
});
Loading...




Giving users
 feedback
Ajax order

1. ajaxStart

2. ajaxSuccess (or ajaxError)

3. ajaxComplete


    http://api.jquery.com/?s=ajax
$('#status').ajaxStart(function () {
  $(this).fadeIn();
}).ajaxComplete(function () {
  $(this).fadeOut();
});
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)
Plugins
What’s a plugin?
A plugin is nothing more than a
custom jQuery method created to
extend the functionality of the jQuery
object


$(‘ul’).myPlugin()
Plugin design in 6 steps
Step 1:
create a private
scope for $ alias
<!DOCTYPE html><html><body>
<script src=”jquery.js”></script>
<script>
(function ($) {

})(jQuery);
</script></body></html>
Step 2:
 attach plugin to fn
alias (aka prototype)
<!DOCTYPE html><html><body>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  $(this).text(
     $(this).text().replace(/hate/g, ‘love’)
  );
}; // end of plugin
})(jQuery);
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  $(this).text(
     $(this).text().replace(/hate/g, ‘love’)
  );
}; // end of plugin
})(jQuery);

$(‘p’).notHate();
</script></body></html>
Step 3:
add implicit iteration
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g, ‘love’)
    );
  });
}; // end of plugin
})(jQuery);

$(‘p’).notHate();
</script></body></html>
Step 4:
enable chaining
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g, ‘love’)
    );
  });
}; // end of plugin
})(jQuery);

$(‘p’).notHate().hide();
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
 this == jQuery
(function ($) {
$.fn.notHate = function () {
  return this.each(function () {
     $(this).text(
        $(this).text().replace(/hate/g, ‘love’)
     );
  });
}; // end of plugin
})(jQuery);

$(‘p’).notHate().hide();
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
 this == jQuery
(function ($) {
$.fn.notHate = function () {
  return this.each(function () {
     $(this).text(
        $(this).text().replace(/hate/g, ‘love’)
     );
  });
}; // end of == DOM element
           this plugin
})(jQuery);

$(‘p’).notHate().hide();
</script></body></html>
Step 5:
add default options
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ $.fn.notHate.defaults.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate();
</script></body></html>
Step 6:
add custom options
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function () {
  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ $.fn.notHate.defaults.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function (options) {
  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ $.fn.notHate.defaults.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function (options) {
  var settings = $.extend({},
  ➥ $.fn.notHate.defaults, options);

  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ $.fn.notHate.defaults.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
<!DOCTYPE html><html><body>     http://jsbin.com/ifuga/edit
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function (options) {
  var settings = $.extend({},
  ➥ $.fn.notHate.defaults, options);

  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ settings.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function (options) {
  var settings = $.extend({},
  ➥ $.fn.notHate.defaults, options);

  return this.each(function () {
    $(this).text(
       $(this).text().replace(/hate/g,
       ➥ settings.text)
    );
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
<!DOCTYPE html><html><body>
<p>I hate jQuery!</p>
<p>I mean really hate jQuery!</p>
<script src=”jquery.js”></script>
<script>
(function ($) {
$.fn.notHate = function (options) {
  var settings = $.extend({},
  ➥ $.fn.notHate.defaults, options);

  return this.text(function (i, text) {
    return text.replace(/hate/g,
      ➥ settings.text);
  });
}; // end of plugin
$.fn.notHate.defaults = {text:‘love’};
})(jQuery);

$(‘p’).notHate({text: ‘love-love-love’});
</script></body></html>
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?
      To contact me after my presentation
      – text NHT to INTRO (46876)


      Or --
      remy@leftlogic.com
      @rem

Yearning jQuery