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

8,163
-1

Published on

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

No Downloads
Views
Total Views
8,163
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
87
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

Rediscovering JavaScript: The Language Behind The Libraries

  1. 13th September 2010 Rediscovering JavaScript The Language BehindThe Libraries Simon Willison, Think Vitamin JavaScript
  2. Coming up... ✤ JavaScript, the language ✤ Object fundamentals ✤ Functions and closures ✤ Prototype inheritance ✤ JavaScript, the Libraries ✤ Event handling ✤ Animation ✤ Drag ‘n’ Drop
  3. Let’s go back in time to 2004...
  4. My phone looked like this: Nokia 7610
  5. No one took JavaScript seriously
  6. Well... almost no one...
  7. “Selling the Future of DHTML”
  8. Then, 2005 happened
  9. May 9th, 2005 Http://www.flickr.com/photos/nataliedowne/14517351/ (me, in 2005)
  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. 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. Different philosophical approaches
  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. MochiKit:“make JS like Python” var theSum = sum(takewhile( partial(operator.gt, 10), imap( partial(operator.mul, 2), count() ) ));
  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. 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. How can one language support so many different programming styles?
  18. JavaScript, the Language
  19. Objects
  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. 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. 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. (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. 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. Iteration through arrays > var a = ["dog", "cat", "chicken"]; > for (var i = 0; i < a.length; i++) { console.log(a[i]); } dog cat chicken
  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. Functions
  28. Functions
  29. Functions // What could be simpler? function addTwoNumbers(a, b) { var total = a + b; // A local variable return total; } > addTwoNumbers(2, 4) 6
  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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. “this” is JavaScript’s magic word
  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. 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. 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. 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. 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. 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. 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. 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. Prototype chain var simon = new Person(...); simon.toString(); Try simon.toString() ... Try Person.prototype.toString() ... Try Object.toString() ... Give up
  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. Let’s talk about libraries
  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. We’ll start with something easy... Events
  55. Adding events var link = document.getElementById(‘mylink’); link.onclick = function() { alert(this.href); return false; }
  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. 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. ✤ 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. 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. 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. 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. 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. http://www.quirksmode.org/js/ for more
  64. How about animation?
  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. Drag and Drop?
  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. 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. http://developer.yahoo.com/ypatterns/richinteraction/dragdrop/modules.html
  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. So how does jQuery do it?
  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. 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. 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. 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. 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. 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. 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. Moral: Learn JavaScript properly, but don’t write your own library unless you’re a total glutton for punishment
  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.

×