Your SlideShare is downloading. ×
0
13th September 2010
Rediscovering JavaScript
The Language BehindThe Libraries
Simon Willison, Think Vitamin JavaScript
Coming up...
✤ JavaScript, the language
✤ Object fundamentals
✤ Functions and closures
✤ Prototype inheritance
✤ JavaScrip...
Let’s go back in time to 2004...
My phone
looked like this:
Nokia 7610
No one took JavaScript seriously
Well... almost no one...
“Selling the Future of DHTML”
Then, 2005 happened
May 9th, 2005 Http://www.flickr.com/photos/nataliedowne/14517351/
(me, in 2005)
Also in 2005
✤ Gmail had its first birthday, still in invite-only beta
✤ Google Maps launched February 8th
✤ The term “Ajax...
A flurry of library activity
✤ February 2005: First Prototype.js
✤ March 2005: First public MochiKit code
✤ YUI started de...
Different philosophical approaches
Prototype:“make JS like Ruby”
Sortable.tree(element, arguments[1]).children.map(function(item) {
return [
name + Sortable....
MochiKit:“make JS like Python”
var theSum = sum(takewhile(
partial(operator.gt, 10),
imap(
partial(operator.mul, 2),
count...
YUI:“make JS like Java”
YAHOO.namespace("example.panel");
function initWait(ev) {
YAHOO.example.panel.wait = new YAHOO.wid...
jQuery:“make JS like jQuery”
$('form#login')
.find('label.optional').hide().end()
.find('input:password').css('border', '1...
How can one language support so
many different programming styles?
JavaScript, the Language
Objects
Everything in JavaScript is an object
Strings and numbers
> "A string".length
8
> 123.toString()
SyntaxError: Unexpected t...
You can make your own objects
// The same thing:
var simon = new Object();
var simon = {};
// Also the same:
simon.name = ...
You can loop through properties
> var simon = {
name: "Simon Willison",
age: 29
};
> for (var prop in simon) {
console.log...
(almost) Everything in JavaScript is a
property on an object
> parseInt("100 bunnies");
100
> parseInt === window.parseInt...
Arrays
> var a = new Array(); // Old-school
> var a = []; // Literal syntax
> var a = ["dog", "cat", "chicken"];
> a.lengt...
Iteration through arrays
> var a = ["dog", "cat", "chicken"];
> for (var i = 0; i < a.length; i++) {
console.log(a[i]);
}
...
Tricksy array iteration
> var a = ["dog", "cat", "chicken"];
> for (var i = 0, item; item = a[i]; i++) {
console.log(item)...
Functions
Functions
Functions
// What could be simpler?
function addTwoNumbers(a, b) {
var total = a + b; // A local variable
return total;
}
...
Functions
// What could be simpler?
function addTwoNumbers(a, b) {
var total = a + b; // A local variable
return total;
}
...
Functions
// What could be simpler?
function addTwoNumbers(a, b) {
var total = a + b; // A local variable
return total;
}
...
Function parameters are more
like guidelines
// arguments is a magic array-like object
function add() {
var sum = 0;
for (...
Anonymous functions
var add = function() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += argumen...
Modern array iteration
> var a = ["dog", "cat"];
> a.forEach(function(item) {
console.log(item);
}
dog
cat
> a.forEach(fun...
Closures
function makeOp(op, x) {
switch(op) {
case '+':
return function(y) { return y + x };
case '-':
return function(y)...
How does this work?
✤ Remember “everything in JavaScript is a property of an object”?
✤ Imagine that local variables belon...
Real-world closure example
function revealer(el, duration) {
return function(ev) {
ev.preventDefault();
el.show(duration);...
Functions and objects
function makePerson(first, last) {
return {
"first": first,
"last": last
}
}
function personFullName...
First attempt at methods
function makePerson(first, last) {
return {
"first": first,
"last": last,
"fullName": function() ...
What the heck is “this”?
✤ When you write:
> simon.fullName();
✤
fullName() is executed with this pointing to simon.
✤ If ...
“this” is JavaScript’s magic word
You can control what this is
> simon = makePerson("Simon", "Willison");
> nat = makePerson("Natalie", "Downe");
> nat.full...
call v.s. apply
✤ Call lets you specify both the value of this and the arguments that
should be passed:
✤ myFunction.call(...
Constructors
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = function() {
return this...
What does “new” do?
✤ var simon = new Person(first, last);
✤ Creates an empty object: {}
✤ Executes the Person function wi...
Prototype inheritance
The following is wasteful
function Person(first, last) {
this.first = first;
this.last = last;
this....
Prototype inheritance
function Person(first, last) { this.first = first; this.last = last; }
Person.prototype.fullName = f...
You can extend built-in classes
> "hello".reversed();
TypeError: Object hello has no method 'reversed'
> String.prototype....
That doesn’t mean you should
✤ Don’t modify objects you don’t own
✤ Extending Object.prototype breaks the (for var prop in...
Prototype chain
var simon = new Person(...);
simon.toString();
Try simon.toString()
...
Try Person.prototype.toString()
.....
Advanced prototype chains
function Mammal() { ... }
Mammal.prototype.eatThings = ...
Person.prototype = new Mammal();
Pers...
Let’s talk about libraries
In 2004, no one used libraries...
✤ Well, sort of...
✤ If you wanted to write anything interesting in JavaScript, there we...
We’ll start with something easy... Events
Adding events
var link = document.getElementById(‘mylink’);
link.onclick = function() {
alert(this.href);
return false;
}
Adding more than one event?
// W3C standard browsers
var link = document.getElementById('mylink');
link.addEventListener('...
The addEvent function
function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListene...
✤ What if you want to keep track of the event listeners that have been
added?
✤ In particular so you can manually de-regis...
Dean Edwards addEvent
function addEvent(element, type, handler) {
" if (element.addEventListener) {
" " element.addEventLi...
Dean Edwards addEvent (2)
function removeEvent(element, type, handler) {
" if (element.removeEventListener) {
" " element....
Dean Edwards addEvent (3)
function fixEvent(event) {
" // add W3C standard event methods
" event.preventDefault = fixEvent...
Want to know where the mouse is?
addEvent(div, 'mouseover', function(ev) {
" if (!ev) var ev = window.event; // For IE
" v...
http://www.quirksmode.org/js/ for more
How about animation?
Animate a div moving across a screen
✤ Easy! Just use setInterval() to move it left 10 pixels every 10th of a
second
✤ But...
Drag and Drop?
✤ Watch out for an onmousedown event over the object you want to
drag
✤ Attach an onmousemove event to the body, and move ...
Drag and drop, for real
✤ Need to be able to distinguish between a click and a drag
✤ How about... a drag starts when
✤ Th...
http://developer.yahoo.com/ypatterns/richinteraction/dragdrop/modules.html
The truth is...
✤ By the time you’ve implemented event handling, basic animation,
DOM manipulation and drag and drop, you’...
So how does jQuery do it?
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
A simple example
jQuery(function($) {
var div = $('#sessions-placeholder');
$('ul.tags a').click(function(ev) {
ev.prevent...
Moral:
Learn JavaScript properly, but
don’t write your own library
unless you’re a total glutton for
punishment
http://lanyrd.com/scch
Upcoming SlideShare
Loading in...5
×

Rediscovering JavaScript: The Language Behind The Libraries

7,074

Published on

Published in: Technology
0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,074
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
86
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

Transcript of "Rediscovering JavaScript: The Language Behind The Libraries"

  1. 1. 13th September 2010 Rediscovering JavaScript The Language BehindThe Libraries Simon Willison, Think Vitamin JavaScript
  2. 2. Coming up... ✤ JavaScript, the language ✤ Object fundamentals ✤ Functions and closures ✤ Prototype inheritance ✤ JavaScript, the Libraries ✤ Event handling ✤ Animation ✤ Drag ‘n’ Drop
  3. 3. Let’s go back in time to 2004...
  4. 4. My phone looked like this: Nokia 7610
  5. 5. No one took JavaScript seriously
  6. 6. Well... almost no one...
  7. 7. “Selling the Future of DHTML”
  8. 8. Then, 2005 happened
  9. 9. May 9th, 2005 Http://www.flickr.com/photos/nataliedowne/14517351/ (me, in 2005)
  10. 10. Also in 2005 ✤ Gmail had its first birthday, still in invite-only beta ✤ Google Maps launched February 8th ✤ The term “Ajax” was coined February 18th by Jesse James Garrett ✤ Ajaxian.com launched March 10th
  11. 11. A flurry of library activity ✤ February 2005: First Prototype.js ✤ March 2005: First public MochiKit code ✤ YUI started development internally at Yahoo! in 2005 (first public release was February 2006) ✤ jQuery released at BarCamp Boston in January 2006
  12. 12. Different philosophical approaches
  13. 13. Prototype:“make JS like Ruby” Sortable.tree(element, arguments[1]).children.map(function(item) { return [ name + Sortable._constructIndex(item) + "[id]=" + encodeURIComponent(item.id) ].concat(item.children.map(arguments.callee)); }).flatten().join('&');
  14. 14. MochiKit:“make JS like Python” var theSum = sum(takewhile( partial(operator.gt, 10), imap( partial(operator.mul, 2), count() ) ));
  15. 15. YUI:“make JS like Java” YAHOO.namespace("example.panel"); function initWait(ev) { YAHOO.example.panel.wait = new YAHOO.widget.Panel("wait", { width: "240px", modal: true, effect: { effect:YAHOO.widget.ContainerEffect.FADE, duration:0.5 } }); YAHOO.example.panel.wait.beforeRenderEvent.subscribe(function() { debug('beforeRenderEvent Fired..'); }, YAHOO.example.panel.wait, true); YAHOO.example.panel.wait.setHeader("Loading (1), please wait..."); }
  16. 16. jQuery:“make JS like jQuery” $('form#login') .find('label.optional').hide().end() .find('input:password').css('border', '1px solid red').end() .submit(function(){ return confirm('Are you sure you want to submit?'); });
  17. 17. How can one language support so many different programming styles?
  18. 18. JavaScript, the Language
  19. 19. Objects
  20. 20. Everything in JavaScript is an object Strings and numbers > "A string".length 8 > 123.toString() SyntaxError: Unexpected token ILLEGAL > (123).toString() “123” Even functions: > function hello() { alert("hello") } > hello.toString() "function hello() { alert("hello") }"
  21. 21. You can make your own objects // The same thing: var simon = new Object(); var simon = {}; // Also the same: simon.name = "Simon Willison"; // name is a property simon["name"] = "Simon Willison"; // Object literal syntax is most useful: var simon = { name: "Simon Willison", age: 29 };
  22. 22. You can loop through properties > var simon = { name: "Simon Willison", age: 29 }; > for (var prop in simon) { console.log(prop + ': ' + simon[prop]); } name: Simon age: 29 (more on this later...)
  23. 23. (almost) Everything in JavaScript is a property on an object > parseInt("100 bunnies"); 100 > parseInt === window.parseInt // window is the global object true > window === window.window true > window === window.window.window true > true === window.true SyntaxError: Unexpected token true
  24. 24. Arrays > var a = new Array(); // Old-school > var a = []; // Literal syntax > var a = ["dog", "cat", "chicken"]; > a.length; 3 > a[0] "dog" > a[2] "chicken" > a[3] undefined
  25. 25. Iteration through arrays > var a = ["dog", "cat", "chicken"]; > for (var i = 0; i < a.length; i++) { console.log(a[i]); } dog cat chicken
  26. 26. Tricksy array iteration > var a = ["dog", "cat", "chicken"]; > for (var i = 0, item; item = a[i]; i++) { console.log(item); } dog cat chicken // But watch out for falsey values: > var a = [123, 0, 12, 443]; > for (var i = 0, item; item = a[i]; i++) { console.log(item); } 123
  27. 27. Functions
  28. 28. Functions
  29. 29. Functions // What could be simpler? function addTwoNumbers(a, b) { var total = a + b; // A local variable return total; } > addTwoNumbers(2, 4) 6
  30. 30. Functions // What could be simpler? function addTwoNumbers(a, b) { var total = a + b; // A local variable return total; } > addTwoNumbers(2, 4) 6 > addTwoNumbers() NaN
  31. 31. Functions // What could be simpler? function addTwoNumbers(a, b) { var total = a + b; // A local variable return total; } > addTwoNumbers(2, 4) 6 > addTwoNumbers() NaN > addTwoNumbers(2, 4, 8) 6
  32. 32. Function parameters are more like guidelines // arguments is a magic array-like object function add() { var sum = 0; for (var i = 0, j = arguments.length; i < j; i++) { sum += arguments[i]; } return sum; } > add(1, 3, 4, 5, 0, 5); 18
  33. 33. Anonymous functions var add = function() { var sum = 0; for (var i = 0, j = arguments.length; i < j; i++) { sum += arguments[i]; } return sum; } var added = (function() { var a = 2, b = 5; // Local variables return a + b; })();
  34. 34. Modern array iteration > var a = ["dog", "cat"]; > a.forEach(function(item) { console.log(item); } dog cat > a.forEach(function(item, index) { console.log(index + ': ' + item); } 0: dog 1: cat
  35. 35. Closures function makeOp(op, x) { switch(op) { case '+': return function(y) { return y + x }; case '-': return function(y) { return y - x }; case '/': return function(y) { return y / x }; case '*': return function(y) { return y * x }; } } > var third = makeOp('/', 3); > var dbl = makeOp('*', 2); > console.log(third(12) + ' ' + dbl(8)); 4 16
  36. 36. How does this work? ✤ Remember “everything in JavaScript is a property of an object”? ✤ Imagine that local variables belong to a “local scope” object, which gets created when a function is executed ✤ Now imagine this object can stick around after the function has finished executing ✤ A closure is a function plus the scope in which that function was created ✤ Since closures capture state, you can use them as a kind of object
  37. 37. Real-world closure example function revealer(el, duration) { return function(ev) { ev.preventDefault(); el.show(duration); } } $("#mylink').click(revealer($('#panel'), 500); $("#mylink2').click(revealer($('#panel2'), 1000);
  38. 38. Functions and objects function makePerson(first, last) { return { "first": first, "last": last } } function personFullName(person) { return person.first + ' ' + person.last; } > simon = makePerson("Simon", "Willison"); > personFullName(simon) "Simon Willison"
  39. 39. First attempt at methods function makePerson(first, last) { return { "first": first, "last": last, "fullName": function() { return this.first + ' ' + this.last; } } } > simon = makePerson("Simon", "Willison"); > simon.fullName(); "Simon Willison"
  40. 40. What the heck is “this”? ✤ When you write: > simon.fullName(); ✤ fullName() is executed with this pointing to simon. ✤ If you call a method without using the '.' operator, this is set to the global object, i.e. window. > var fullNameMethod = simon.fullName; > fullNameMethod(); undefined undefined
  41. 41. “this” is JavaScript’s magic word
  42. 42. You can control what this is > simon = makePerson("Simon", "Willison"); > nat = makePerson("Natalie", "Downe"); > nat.fullName(); "Natalie Downe" > nat.fullName.call(simon); "Simon Willison" > simon.fullName.apply(nat); "Natalie Downe"
  43. 43. call v.s. apply ✤ Call lets you specify both the value of this and the arguments that should be passed: ✤ myFunction.call(myThis, arg1, arg2, arg3); ✤ Apply lets you do the same thing, but pass an array of arguments instead: ✤ myFunction.apply(myThis, [arg1, arg2, arg3]); ✤ (I always have to look this up)
  44. 44. Constructors function Person(first, last) { this.first = first; this.last = last; this.fullName = function() { return this.first + ' ' + this.last; } } > var simon = new Person("Simon", "Willison"); > s.fullName(); "Simon Willison"
  45. 45. What does “new” do? ✤ var simon = new Person(first, last); ✤ Creates an empty object: {} ✤ Executes the Person function with this set to the new empty object ✤ Adds Person.prototype to the object's prototype chain
  46. 46. Prototype inheritance The following is wasteful function Person(first, last) { this.first = first; this.last = last; this.fullName = function() { return this.first + ' ' + this.last; } } How can we avoid creating a fullName function for every object?
  47. 47. Prototype inheritance function Person(first, last) { this.first = first; this.last = last; } Person.prototype.fullName = function() { return this.first + ' ' + this.last; } > var simon = new Person("Simon", "Willison"); > simon.fullName(); "Simon Willison" > simon.fullNameReversed(); TypeError: Object #<a Person> has no method 'fullNameReversed' Person.prototype.fullNameReversed = function() { return this.last + ', ' + this.first; } > simon.fullNameReversed(); "Willison, Simon"
  48. 48. You can extend built-in classes > "hello".reversed(); TypeError: Object hello has no method 'reversed' > String.prototype.reversed = function() { var r = ''; for (var i = this.length - 1; i >= 0; i--) { r += this[i]; } return r; } > "hello".reversed(); "olleh"
  49. 49. That doesn’t mean you should ✤ Don’t modify objects you don’t own ✤ Extending Object.prototype breaks the (for var prop in obj) idiom ✤ Prototype.js added document.getElementsByClassName ✤ Then Mozilla added document.getElementsByClassName... ✤ The behaviour was slightly different, so code broke ✤ If you’d written your own Array.forEach() method, today your code would be clashing with the new forEach() method in JavaScript 1.6
  50. 50. Prototype chain var simon = new Person(...); simon.toString(); Try simon.toString() ... Try Person.prototype.toString() ... Try Object.toString() ... Give up
  51. 51. Advanced prototype chains function Mammal() { ... } Mammal.prototype.eatThings = ... Person.prototype = new Mammal(); Person.prototype.learnToRead = ... var simon = new Person(...); simon.eatThings(); Try simon.eatThings() ... Try Person.prototype.eatThings() ... Try Mammal.eatThings() ... Try Object.eatThings() ... Give up
  52. 52. Let’s talk about libraries
  53. 53. In 2004, no one used libraries... ✤ Well, sort of... ✤ If you wanted to write anything interesting in JavaScript, there were a few utility functions you needed in every single project
  54. 54. We’ll start with something easy... Events
  55. 55. Adding events var link = document.getElementById(‘mylink’); link.onclick = function() { alert(this.href); return false; }
  56. 56. Adding more than one event? // W3C standard browsers var link = document.getElementById('mylink'); link.addEventListener('click', function() { alert("Hello"); return false; }); // IE 6 link.attachEvent("onclick", function() { alert("Hello"); return false; );
  57. 57. The addEvent function function addEvent(obj, evType, fn, useCapture){   if (obj.addEventListener){     obj.addEventListener(evType, fn, useCapture);     return true;   } else if (obj.attachEvent){     var r = obj.attachEvent("on"+evType, fn);     return r;   } else {     alert("Handler could not be attached");   } } // DON'T USE THIS THOUGH http://www.scottandrew.com/weblog/articles/cbs-events
  58. 58. ✤ What if you want to keep track of the event listeners that have been added? ✤ In particular so you can manually de-register them when the page unloads, to clean up potential memory leaks in IE ✤ addEvent doesn't fix the different event objects for you, so you still have to work around browser differences there addEvent drawbacks
  59. 59. Dean Edwards addEvent function addEvent(element, type, handler) { " if (element.addEventListener) { " " element.addEventListener(type, handler, false); " } else { " " // assign each event handler a unique ID " " if (!handler.$$guid) handler.$$guid = addEvent.guid++; " " // create a hash table of event types for the element " " if (!element.events) element.events = {}; " " // create a hash table of event handlers for each element/event pair " " var handlers = element.events[type]; " " if (!handlers) { " " " handlers = element.events[type] = {}; " " " // store the existing event handler (if there is one) " " " if (element["on" + type]) { " " " " handlers[0] = element["on" + type]; " " " } " " } " " // store the event handler in the hash table " " handlers[handler.$$guid] = handler; " " // assign a global event handler to do all the work " " element["on" + type] = handleEvent; " } }; // a counter used to create unique IDs addEvent.guid = 1;
  60. 60. Dean Edwards addEvent (2) function removeEvent(element, type, handler) { " if (element.removeEventListener) { " " element.removeEventListener(type, handler, false); " } else { " " // delete the event handler from the hash table " " if (element.events && element.events[type]) { " " " delete element.events[type][handler.$$guid]; " " } " } }; function handleEvent(event) { " var returnValue = true; " // grab the event object (IE uses a global event object) " event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); " // get a reference to the hash table of event handlers " var handlers = this.events[event.type]; " // execute each event handler " for (var i in handlers) { " " this.$$handleEvent = handlers[i]; " " if (this.$$handleEvent(event) === false) { " " " returnValue = false; " " } " } " return returnValue; };
  61. 61. Dean Edwards addEvent (3) function fixEvent(event) { " // add W3C standard event methods " event.preventDefault = fixEvent.preventDefault; " event.stopPropagation = fixEvent.stopPropagation; " return event; }; fixEvent.preventDefault = function() { " this.returnValue = false; }; fixEvent.stopPropagation = function() { " this.cancelBubble = true; };
  62. 62. Want to know where the mouse is? addEvent(div, 'mouseover', function(ev) { " if (!ev) var ev = window.event; // For IE " var posx = 0; " var posy = 0; " if (ev.pageX || ev.pageY) { " " posx = ev.pageX; " " posy = ev.pageY; " } else if (e.clientX || e.clientY) { " " posx = e.clientX + document.body.scrollLeft " " " + document.documentElement.scrollLeft; " " posy = e.clientY + document.body.scrollTop " " " + document.documentElement.scrollTop; " } }); // http://www.quirksmode.org/js/events_properties.html
  63. 63. http://www.quirksmode.org/js/ for more
  64. 64. How about animation?
  65. 65. Animate a div moving across a screen ✤ Easy! Just use setInterval() to move it left 10 pixels every 10th of a second ✤ But... what if you're animating lots of things, and the user's computer can't keep up... ✤ Solution: figure out where you want it to be in 2 seconds time, then check how much time has elapsed each time round the animation loop and adjust the position accordingly
  66. 66. Drag and Drop?
  67. 67. ✤ Watch out for an onmousedown event over the object you want to drag ✤ Attach an onmousemove event to the body, and move the element with the mouse ✤ Watch for onmouseup, and remove the mousemove handler ✤ Simple right? Drag and drop implementation
  68. 68. Drag and drop, for real ✤ Need to be able to distinguish between a click and a drag ✤ How about... a drag starts when ✤ The user moves their mouse at least 5 pixels ✤ OR... the user holds down the mose button on the draggable for at least a full second ✤ Need to restrict the area in which the draggable can be dragged ✤ Highlight drop targets when the draggable intersects them ✤ Revert the position of the item if it’s dropped in the wrong place...
  69. 69. http://developer.yahoo.com/ypatterns/richinteraction/dragdrop/modules.html
  70. 70. The truth is... ✤ By the time you’ve implemented event handling, basic animation, DOM manipulation and drag and drop, you’ve re-invented a sizable chunk of jQuery, YUI or Dojo, probably with more lines of code and definitely with a whole lot more bugs.
  71. 71. So how does jQuery do it?
  72. 72. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  73. 73. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  74. 74. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  75. 75. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  76. 76. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  77. 77. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  78. 78. A simple example jQuery(function($) { var div = $('#sessions-placeholder'); $('ul.tags a').click(function(ev) { ev.preventDefault(); var a = $(this); div.html( '<img src="/static/img/loaders/ajax-loader-blue.gif" ' + 'style="margin-bottom: 1em" />' ); div.load(a.attr('href') + '?ajax=1'); a.closest('ul').find('li').removeClass('selected'); a.closest('li').addClass('selected'); }); });
  79. 79. Moral: Learn JavaScript properly, but don’t write your own library unless you’re a total glutton for punishment
  80. 80. http://lanyrd.com/scch
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×