getting started with jquery - adam's note · pdf file12.08.2000 · dom...

251
Jquery Tutorial

Upload: doancong

Post on 06-Mar-2018

219 views

Category:

Documents


1 download

TRANSCRIPT

Jquery Tutorial

Outline• Philosophy of jQuery and API Walkthrough

• Dev Tools

• Bare-bones JavaScript

• jQuery Selectors and Traversing

DOM Scripting

DOM Scripting

•Based on web standards

•Tests features, not browsers

•Unobtrusive

DOM Scripting

Books

Jeremy Keith Peter-Paul Koch Jonathan Snook

domscripting.com quirksmode.org snook.ca

Unobtrusive

custom.js

Behavior Content

index.html

Presentation

style.css

DOM Scripting•Verbose

if (!document.getElementsByTagName) { return false; }

var quotes =

document.getElementsByTagName("blockquote");

for (var i=0; i<quotes.length; i++) {

var source = quotes[i].getAttribute("cite");

if (source) {

var link = document.createElement("a");

link.setAttribute("href",source);

var text = document.createTextNode("source");//!?

link.appendChild(text);

var para = document.createElement("p");

para.className = "attribution";

para.appendChild(link);

quotes[i].appendChild(para);

}

}

jQueryInteraction for the Masses

Just a few of jQuery's

Benefits•Lets you move quickly from beginner to

advanced

•Improves developer efficiency

•Excellent documentation // pats self on back

•Unobtrusive from the ground up

•Reduces browser inconsistencies

•At its core, a simple concept

Unobtrusive

jquery.js

custom.js

Behavior Content

index.html

Presentation

style.css

Reduces browser

inconsistencies•Example:

Get the height of the viewport…

var x,y;

if (self.innerHeight) { // all except Explorer

x = self.innerWidth;

y = self.innerHeight;

}

else if (document.documentElement &&

document.documentElement.clientHeight) {

// Explorer 6 Strict Mode

x = document.documentElement.clientWidth;

y = document.documentElement.clientHeight;

}

else if (document.body) { // other Explorers

x = document.body.clientWidth;

y = document.body.clientHeight;

}

DOM Scripting

var x = $(window).width();

var y = $(window).height();

jQuery

Documentation &

Support– API: api.jquery.com

– Forum: forum.jquery.com

– IRC: irc.freenode.net, #jquery

– Coming Soon: learn.jquery.com

Simple Concept

• Find something

• Do something

Find Something"Select" elements in the document

Do Something

Do Something

1. Let elements "listen" for something to happen

• the document is ready

• user does something

• another "listener" acts

• a certain amount of time elapses

Do Something

2. … and then do something

a. Manipulate elements

b. Animate elements

c. Communicate with the server

Dev Tools

Dev Tools

• up to five browsers to test against

• Firefox

• Chrome

• Internet Explorer

• Safari

• Opera

• developer tools can make your life much easier

Browser Support

• Modernizr

• http://www.modernizr.com

• Can I Use?

• http://caniuse.com

Code Sharing

• jsfiddle

• http://jsfiddle.net/

• jsbin

• http://jsbin.com

• TextMate

• jQuery Bundle:

http://github.com/kswedberg

• JavaScript Tools Bundle:

http://github.com/subtleGradient

• Sublime Text 2

• MacVim

• Espresso

• jQuery Sugar:

• code.google.com/p/espresso-jquery-sugar

Text EditorsMac OS X

• E

• jQuery Bundle:

http://github.com/kswedberg

• Eclipse / Aptana

• Notepad++

• Visual Studio

• and so on.

Text EditorsWindows

• Console

• DOM Viewer

• JavaScript debugger

• Net view

• Lots of extensions

http://getfirebug.com/wiki/index.php/Firebug_Extensions

Firefox: Firebug

Chrome Developer

Tools• In many ways, leapfrogging Firebug

• Live debugging, code changing

• Lots of "hidden" goodies

• http://code.google.com/chrome/devtools/

• Paul Irish screencast: http://youtu.be/nOEw9iiopwI

• Included since Safari 3.1

• Similar to Chrome Dev Tools, but not as advanced

• Activate via Preferences > Advanced

Safari: Developer

Menu

• Much, much better than in previous versions.

• Finally includes a console.

Internet Explorer 8+:

Developer Tools

• CompanionJS:

tinyurl.com/companionjs

• IETester:

tinyurl.com/dbtester

• MS Developer Toolbar:

tinyurl.com/msdevtoolbar

• Script Debugger:

tinyurl.com/msscriptdebug

• None of them comes even close to the tools available in

other browsers

Internet Explorer <= 7

Bare-bones

JavaScript

The Basics

• Strings: textual content. wrapped in quotation marks

(single or double).

• 'hello, my name is Karl'

• "hello, my name is Karl"

• Numbers: integer (2) or floating point (2.4) or octal (012)

or hexadecimal (0xff) or exponent literal (1e+2)

• Booleans: true or false

In JavaScript, you can work with the following things:

The Basics

• Arrays: simple lists. indexed starting with 0

• ['Karl', 'Sara', 'Ben', 'Lucia']

• ['Karl', 2, 55]

• [ ['Karl', 'Sara'], ['Ben', 'Lucia']]

• Objects: lists of key, value pairs

• {firstName: 'Karl', lastName: 'Swedberg'}

• {parents: ['Karl', 'Sara'], kids: ['Ben', 'Lucia']}

In JavaScript, you can work with the following things:

Variables

• Always declare your variables!

• If you don't, they will be placed in the global scope

(more about that later).

• bad: myName = 'Karl';

• good: var myName = 'Karl';

• still good: var myName = 'Karl';

// more stuff

myName = 'Joe';

Conditionals and

Operators

• conditionals:

• if, else

• switch

• operators:

• +, -, *, %, ++, --

• >, <, ==, !=, >=, <=, ===, !==

• !, &&, ||

Loops

• Loops iterate through a list of some kind.

• A common pattern in JavaScript is to build a list, or

collection, and then do something with each item in that

list.

Loops

• CSS uses implicit iteration.

• div { color: red; } /* applies to ALL divs */

• JavaScript relies on explicit iteration. Must explicitly loop

through each div

• jQuery allows for both (because it does the looping for

you)

Loops

• The two most common loops...

• for loops — for general-purpose iteration. Used with

arrays or array-like objects)

• for-in loops — used with arrays or objects (but don't

use with arrays)

• The other two are...

• while loops

• do-while loops

for (initial value; condition; increment) {

// code block

}

for Loops

• three statements and a code block

1. initial value

2. condition

3. increment

for Loopsfor (var i = 0; i < 3; i++) {

alert(i+1);}

This is your variable,

so it can be anything!

(but developers often

use “i”)

for Loopsvar divs = document.getElementsByTagName('div');

for (var i = 0; i < divs.length; i++) {// do something with each div individually

divs[i].style.color = 'red';

}

for Loopsvar divs = document.getElementsByTagName('div');

// better to store length in variable first

var divCount = divs.length

for (var i = 0; i < divCount; i++) {// do something with each div individually

divs[i].style.color = 'red';

}

for Loopsvar divs = document.getElementsByTagName('div');

// can store it directly in the initializer

for (var i=0, divCount=divs.length; i < divCount; i++) {// do something with each div individually

divs[i].style.color = 'red';

}

for-in Loopsvar family = {

dad: 'Karl',mom: 'Sara',son: 'Benjamin',daughter: 'Lucia'

}

for (var person in family) {alert('The ' + person + ' is ' + family[person]);

}

This is your variable,

so it can be anything!

while and do-whilevar i = 1;

while (i < 4) {

alert(i);

i++;

}

var j = 1;

// code block always executed at least once

do {

alert(j);

j++;

} while (j < 4)

Functions

The Basics: Functions

• Functions allow you to define a block of code, name that block,

and then call it later as many times as you want.

• function myFunction( ) { /* code goes here */ } // defining

• myFunction( ) // calling the function myFunction

• You can define functions with parameters

• function myFunction(param1, param2 ) { /* code goes here */

}

• You can call functions with arguments:

• myFunction('one', 'two')

In JavaScript, you can also work with functions:

Functions// define a functionfunction doSomething() {

alert('I am something');}

// call the functiondoSomething();

Functions// define a functionfunction sumThing(a, b) {

return a + b;}

// call the functionalert( sumThing(1, 2) );

Functions// define a functionfunction sumThing(a, b) {

return a + b;}

var mySum = sumThing(1, 2);

// call the functionalert( mySum );

The arguments

Object• Every function has an arguments object

• a collection of the arguments passed to the function

when it is called

• an "array-like object" in that it is indexed and has a

length property but can't attach array methods to it

• can be looped through

• allows for variable number of arguments

Functions// call the function

function logThing() {

for (var i=0; i < arguments.length; i++) {

console.log(arguments[i]);

}

}

// call the function

logThing(1, 2, 'three');

/* prints to the console:

>> 1

>> 2

>> three

*/

Exercise

Convert the sumThing function to allow for variable

number of arguments.

function sumThing(a, b) {

return a + b;

}

Use a for loop to loop through the arguments object, adding to a "sum" variable with each iteration.After the loop, return sum.

(Simple) Solution// define a functionfunction sumThing() {

var sum = 0,countArgs = arguments.length;

for (var i = 0; i < countArgs; i++) {sum += arguments[i];

}return sum;

}// call the functionconsole.log( sumThing(1, 2, 4 ) );

function multiple(n) {

function f(x) {

return x * n;

}

return f;

}

var triple = multiple(3);

var quadruple = multiple(4);

console.log( triple(5) ); // 15

console.log( quadruple(5) ); // 20

console.log( multiple(4)(5) ); // 20

Returning Functions• Functions can return other functions

Named vs.

Anonymous

Functions• Named:

• function foo() { } // function declaration

• var foo = function foo() { }; // function expression

• Anonymous:

• var foo = function() { }; // function expression

Anonymous Functions• Prevalent in jQuery

• Good for creating closures

• Used as "callback" functions

• Can be used as object properties (methods)

• let’s take a look ...

$(document).ready(function() {

});

Anonymous Functions• Prevalent in jQuery

function() {

// variables are defined within this scope

// avoid name collisions

}

Anonymous Functions• Good for creating closures

(function() {

// variables are defined within this scope

// avoid name collisions

})();

Anonymous Functions• Good for creating closures

• Can be defined and then immediately invoked:

“immediately invoked function expression,” ( a.k.a. IIFE;

pronounced “iffy”)

(function($) { // "$" is the function's param

})(jQuery); // function is called with "jQuery"

Anonymous Functions• Good for creating closures

• Used by plugins to keep jQuery safe.

$('p').slideDown('slow', function() {

// code in here is not executed

// until after the slideDown is finished

// jQuery calls the code in here when effect

ends

});

Anonymous Functions• Used as "callback" functions

Objects

Objects

• Objects are objects : { }

• Arrays are objects : [ ]

• even Functions are objects : function( ) { }

• jQuery is an object

• Numbers, strings, and booleans (true/false) are primitive

data types, but they have object wrappers.

In JavaScript, everything is an object. Well, almost everything.

Global Object

• location

• parseInt(); parseFloat()

• isNaN()

• encodeURI(); decodeURI()

• setTimeout(); clearTimeout()

• setInterval(); clearInterval()

In the browser environment, the global object is windowIt collects all functions and variables that are global in scope.

Usually implied.

Comes with some useful properties and methods:

Date Object

var now = new Date(); // current date and time

var then = new Date('08/12/2000 14:00');

console.log( then.getTime() ); // 966103200000

console.log( then.toString() );

// Sat Aug 12 2000 14:00:00 GMT-0400 (EDT)

console.log( then.getMonth() ); // 7 !!!!

RegExp ObjectRegular Expression

• Object constructor

• var re = new RegExp('hello');

• Regular expression literal

• var re = /hello/;

Creating a RegExp• Object constructor

• var re = new RegExp('hello');

• Regular expression literal

• var re = /hello/;

Using a RegExpvar text = 'The quick brown fox';

var re = new RegExp('quick');

console.log( re.test(text) ); // true

console.log( /brown/.test(text) ); // true

console.log( /red/.test(text) ); // false

RegExp Syntax• Most characters (incl. all alphanumerics) represent

themselves

• Special characters can be escaped with a backslash (\)

Character Classes• /t.p/ matches 'tap' and 'tip' and 'top'

• /t[ai]p/ matches 'tap' and 'tip', not 'top'

• /t[a-k]p/ matches 'tap' and 'tip', not 'top'

• /t[^m-z]p/ matches 'tap' and 'tip', not 'top'

Repetition• /frog*/ matches 'fro', 'frog', 'frogg', ...

• /frog+/ matches 'frog', 'frogg', ...

• /frog?/ matches 'fro' or 'frog'

• /frog{2,3}/ matches 'frogg' or 'froggg'

Grouping• Grouping

• /(frog)*/ matches "frog" or "frogfrog"

• Alternation

• /th(is|at)/ matches "this" and "that"

Anchor Points• ^ matches the beginning of a string

• $ matches the end of a string

• \b matches word boundaries

Exercises

Write a regular expression that matches any word that

starts with a vowel.

Write a regular expression that matches any HTML tag.

String RegExp

Methods• str.search(re)

• str.match(re)

• str.replace(re, replacement)

• str.split(re)

String Replacementvar str =

'The quick brown fox jumps over the lazy dog.';

console.log(str.replace(/[aeiou]/, '*'));

// Th* quick brown fox jumps over the lazy dog.

RegExp Flags• Placed after closing / character

• Global (g): find as many as possible

• Case insensitive (i)

• Multiline (m): ^ and $ work with newlines

String Replacementvar str =

'The quick brown fox jumps over the lazy dog.';

console.log(str.replace(/[aeiou]/g, '*'));

// Th* q**ck br*wn f*x j*mps *v*r th* l*zy d*g.

console.log(str.replace(/the/gi, 'a'));

// a quick brown fox jumps over a lazy dog.

Backreferencesvar str = 'The quick brown fox jumps over the lazy dog.';

console.log(str.replace(/r(.)/g, '$1x'));

// The quick boxwn fox jumps ove xthe lazy dog.

Replacement

Functionsvar str = 'Kill 5+9 birds with 2+5 stones.';

function add(match, first, second) {return parseInt(first, 10) + parseInt(second, 10);

}str = str.replace(/([0-9]+)\+([0-9]+)/g, add);console.log(str);// Kill 14 birds with 7 stones.

Exercises

Write a function that uppercases all the vowels in

a string.

Write a function that strips the angle brackets

from around any HTML tags in a string.

Greediness• Repeat operators usually match as much of the string as

possible; they are greedy

• JavaScript supports reluctant repetition as well

• Append ? to the repeat operator

And Much More• JavaScript supports most Perl regular expression

extensions

• POSIX character classes

• Unicode character escapes

• Look-ahead assertions

Math Object

• Not a constructor, a singleton

• Gathers useful methods and properties

• Math.PI

• Math.abs(), Math.sin(), Math.pow(),

Math.random(),

• Math.max(), Math.min()

• Math.round(), Math.floor(), Math.ceil()

CSS:

h3 {

font-size: 1.2em;

line-height: 1;

}

JS:

var h3 = {

fontSize: '1.2em',

'line-height': 1

};

CSS Tip

• Object literal notation looks a lot like CSS style rule

notation!

var person = {firstName: 'Karl',lastName: 'Swedberg',hello: function() {return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;}

};

Object Literals• person is the object

• firstName and lastName are properties

• hello is a method (a property that is a function)

var person = {

firstName: 'Karl',

lastName: 'Swedberg',

hello: function() {

return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

},

interests: {

athletic: ['racquetball', 'karate', 'running'],

musical: ['rock', 'folk', 'jazz', 'classical']

}

};

Object Literals• interests is a property and an object

Object Literalsvar person = {

firstName: 'Karl',

lastName: 'Swedberg',

hello: function() {

return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

} // ⬅ notice, no comma here!

};

Object Literals“dot” notation

var person = {

firstName: 'Karl',

lastName: 'Swedberg',

hello: function() {

return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

}

};

// "dot" notation

person.firstName; // 'Karl'

person.lastName; // 'Swedberg'

person.hello() // 'Hello, my name is Karl Swedberg'

Object Literalsarray notation

var person = {

firstName: 'Karl',

lastName: 'Swedberg',

hello: function() {

return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

}

};

// array notation

person['firstName']; // 'Karl'

person['lastName']; // 'Swedberg'

person['hello']() // 'Hello, my name is Karl Swedberg'

var person = {

firstName: 'Karl',

lastName: 'Swedberg',

hello: function() {

return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

},

interests: {

athletic: ['racquetball', 'karate', 'running'],

musical: ['rock', 'folk', 'jazz', 'classical']

}

};

// person['interests']['musical'][1] == ??

// == person.interests.musical[1]

Object Literals

Object Literalsvar person = {firstName: 'Karl',lastName: 'Swedberg',hello: function() {return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;

}

};person.firstName = 'Karl';

var prop = 'firstName';person[ prop ]; // 'Karl'

prop = 'lastName';person[ prop ]; // 'Swedberg'

Object Literalsvar blah;var person = {

firstName: 'Karl',lastName: 'Swedberg',hello: function() {return 'Hello, my name is ' +

this.firstName + ' ' + this.lastName;}

};

for (var el in person) {blah = typeof person[el] == 'function' ?

person[el]() :person[el];

console.log( blah );}

doSomething({

speed: 'fast',

height: 500,

width: 200,

somethingElse: 'yes'

});

doSomething({width: 300});

Object Literals

• Great as function arguments

• single argument allows flexibility when calling the function

JSONJavaScript Object Notation

• a data interchange format. In other words, a format for

passing data back and forth

• “discovered” and popularized by Douglas Crockford

• a subset of JavaScript Object Literal Notation

• a tree-like structure of object(s) and/or array(s)

• no functions

• all strings, including object keys, take double quotes

JSON{

"firstName": "Karl",

"lastName": "Swedberg",

"age": 24,

"interests": {

"athletic": [

"racquetball",

"karate"

]

}

}

JSON{"firstName":"Karl","lastName":"Swedberg","age":24,"intere

sts":{"athletic":["racquetball","karate"]}}

Referencing Scripts

in the HTMLbrowser slides

Selectors &

Traversal

At the heart of

jQuery...• Find something

• Do something

CSS Selectors

• element {}

• #id {}

• .class {}

• selector1, selector2 {}

• ancestor descendant {}

• parent > child {}

• :nth-child() {}

CSS Selectors

• $('element')

• $('#id')

• $('.class')

• $('selector1, selector2')

• $('ancestor descendant')

• $('parent > child')

• $(':nth-child(n)')

(jQuery Equivalents)

CSS Selectors

• $('element')

• $('#id')

• $('.class')

• $('selector1, selector2')

• $('ancestor descendant')

• $('parent > child')

• $(':nth-child(n)')

(jQuery Equivalents)

• and others …

• $('prev + selector')

• $('prevAll ~

selector')$(':nth-

child(an+b')$(':not(select

or)')

• $(':checked')

• $(':disabled')

CSS Attribute

Selectors• $('input[name=firstname\\[\\]]')

• $('[title]') has the attribute

• $('[attr="val"]') attr equals val

• $('[attr!="val"]') attr does not equal val

• $('[attr~="val"]') attr has val as one of space-sep.

vals

• $('[attr^="val"]') attr begins with val

• $('[attr$="val"]') attr ends with val

• $('[attr*="val"]') attr has val anywhere within

Custom Form

Selectors• $('div.myclass :checkbox')

• $(':input') <input>, <textarea>, <select>,

<button>

• $(':text') <input type="text">

• $(':radio') <input type="radio">

• $(':button') <input type="button">, <button>

• $(':selected') <option selected="selected">

• etc.

Custom Misc.

Selectors• $(':animated')

• $(':has(descendant)')

• $(':eq(n)')

• $(':lt(n)')

• $(':gt(n)')

• $(':even')

• $(':odd')

• $(':visible')

$(':hidden')$(':header')$

(':contains(string)')

Selectors• List of all selectors on the jQuery API site

• http://api.jquery.com/category/selectors

Traversal Methods• Move Up

• Move Sideways

• Move Down

• Filter

• Context

• Check

<ul> <li>level 1 <ul class="foo"> <li>level 2

<ul> <li class="bottom"><span>level</span>

3</li> </ul> </li> </ul> </li></ul>

Move Up• parent() : up one level $('li.bottom').parent();

• parents() : up multiple levels $('span').parents('ul');

• parentsUntil() : possibly multiple

$('span').parentsUntil('ul');

<ul> <li>level 1 <ul> <li>level 2 <ul>

<li class="bottom"><span>level</span> 3</li>

</ul> </li> </ul> </li></ul>

Move Up• .closest(selector) : up 0 or more levels

• $('span').closest('ul');

• $('.bottom').closest('li');

Move Sideways• .siblings()

• .next()

• .nextAll()

• .nextUntil()

• .prev()

• .prevAll()

• .prevUntil()

Move Down• .children()

• .find()

Filter• .filter(selector)

• .filter('.some-class')

• .filter(function)

• .filter(function() {

• return $(this).parents('li').length >=

2;

• });

Filter• .not(selector)

• .not('.some-class')

• .not(function)

• .not(function() {

• return $(this).parents('li').length >=

2;

• });

Filter• .slice()

• .slice(2)

• .slice(-2)

• .slice(3, 6)

• .slice(2, -1)

• .eq()

• .eq(2)

• .eq(-2)

Context• $('selector', 'context')

• Different from "or" selector – $('selector1, selector2')

• Same as $('context').find('selector')

• Not worth using; too confusing.

• .add()

• .andSelf()

• .end()

Check• .hasClass(class)

• .is(selector)

** returns a boolean

Traversal Methods• List of all traversal methods on the jQuery API site

• http://api.jquery.com/category/traversing

Chaining• JavaScript has chaining built in.

• 'swap this text'.replace(/w/, 'n').replace(/this/,'that');

• '616-555-1212'.split('-').join('.');

• jQuery takes advantage of this concept by having almost

all methods return the jQuery object.

$('a').parent('li').siblings().find('a')

Chaining

• Chain traversal methods together

$('a').removeClass('old').addClass('new');

Chaining

• Attach multiple behaviors.

$('a').addClass('foo').parent('li').removeClass('foo')

Chaining

• DOM Traversal methods are different from other jQuery

chaining methods!

• New jQuery instance is created with each one.

var lis = $('.container li:first').addClass('first-li')

.next()

.addClass('second-li').end()

.nextAll()

.addClass('not-first-li').end(); // unnecessary; added for symmetry

Chaining

• JavaScript ignores white space, so use it to your advantage.

$('li').removeClass('myclass'); //implicit

$('li').each(function(index) { //explicit$(this).append( ' #' + (index+1) );

});

Looping

• Implicit Iteration

• Explicit Iteration (Looping)

$('li').each(function() {

console.log( this ); // DOM element

console.log( $(this) );

});

this Keyword

• Refers to the current object

• jQuery sets this to matched elements in the jQuery object.

var $listItems = $('li');var numItems = $listItems.length

//no need for length check

$listItems.addClass('pretty');

if (numItems) {

// do something with other elements

}

Tips

• Store selectors used more than once in variables

• Use length property to check existence

• ...but often no need for the check

$('#menu li').each(function(index) { $(this).click(function() {$('#footer li:eq(' + index + ')').addClass('active');

});});

Tips

• Concatenate to pass in a variable

// bad$(':checkbox') // better$('input:checkbox')// best$('input[type="checkbox"]')

Tips

• Avoid jQuery's custom selectors when possible

// uncool$('div:first')

// cool$('div').first();

Tips

• Avoid jQuery's custom selectors when possible

// slower$('li:eq(3)')$('li:lt(3)')

// faster$('li').eq(3)$('li').slice(0, 3)

Tips

• Avoid jQuery's custom selectors when possible

Event Handling

Loading Events

• $(document).ready();

• .load()

• Typically used with $(window)

• Also helpful with images, but be careful!

Multiple “Ready”

Handlers• All are executed

• Execution takes place in order defined

• Can even be defined after the document is ready!

$('button').bind('click', function(event) {// button got clicked

});

Low-level methods.bind()

• add an event listener to elements

• can be a native event like "click"

• can be a custom event, triggered by other code

$('button').bind('click', function(event) {// this is the <button> DOM element// this.className += ' clicked';// $(this) returns jQuery object w/ 1 element// $(this).addClass('clicked');

});

Method Context• The “this” keyword

• DOM Elements vs. jQuery Objects

$('button').trigger('click');

Low-level methods.trigger()

• Trigger events programmatically

• Works for native and custom events

Low-level methods.bind() and .trigger()

// this listens for a click on a span$('span').bind('click', function() {

/* this stuff happens when a span is clicked */

});

// maybe the user will click on a span. Or...

// this triggers any click event bound to a span$('span').trigger('click');

$('button').bind('click', clickListener).bind('click', otherListener);

// unbind all click listeners$('button').unbind('click');

// unbind only the specified listener$('button').unbind('click', clickListener);

Low-level methods .unbind()

• remove an event listener from elements

• remove all listeners, or just the specified one

$('button').click(clickListener);

// == $('button').bind('click', clickListener);

$('button').click();

// == $('button').trigger('click');

Shorthand Syntax

Shorthand Syntax

• .submit()

• .change()

• .focus()

• .focusin()

• .blur()

• .focusout()

• .mouseover()

• .mouseout()

• .mouseenter()

• .mouseleave()

• .mousemove()

• .dblclick()

• .keydown()

• .keypress()

• .keyup()

• .scroll()

• .resize()

• .error()

Event Propagation

a.k.a. “event bubbling”a.k.a. “event bubbling”http://www.quirksmode.org/js/events_order.html

Event Propagation

a.k.a. “event bubbling”http://www.quirksmode.org/js/events_order.html

Two Event Tutorials

• How to ensure that new elements added to the DOM have

events bound to them.

• by using event delegation:

Working with Events, part 1 ( tinyurl.com/eventdelegation )

• by re-binding:

Working with Events, part 2 ( tinyurl.com/eventrebinding )

Event Propagation

• Sometimes we don't want events to bubble.

• Responding to hovers on menus

• (which, maybe, we shouldn't do anyway)

• mouseover vs. mouseenter demo

• alternative event handling architecture

• scales much better

• makes it trivial to add and remove elements

• uses event.target rather than this

*(but jQuery's delegation methods map this to event.target)

• don't ask every element for events, ask a parent instead

• effort is moved from binding to handling

Event delegation

Event Delegation

• .live()

• binds an event handler to the document.

• triggered when element acted upon or one of its ancestors

matches selector

• .die()

• unbinds an event handler

$('button').live('click', function(event) {// button got clicked

});

// unbind click on button$('button').die('click');

Event Delegation• .live() and .die() look just like .bind() and .unbind()

Event Delegation

•Stop using .live() and .die()• They are deprecated as of jQuery 1.7

• They don't work as expected in some situations:

• $('#wrapper').find('a, span').live('click', fn);

• They require events to bubble all the way up to document.

• But, if you're using them successfully with older

jQuery versions, no worries!

Event Delegation• .delegate()

• binds an event handler to jQuery set.

• triggered when element indicated in first argument is

acted upon or one of its ancestors matches the first

argument

• more "optimized" delegation

• .undelegate()

• unbinds an event handler

$('#wrapper').delegate('button', 'click', function(event) {

// button got clicked});

// unbind click on button$('#wrapper').undelegate('button', 'click');

Event Delegation

Event Delegation• Use .delegate() and .undelegate() for event delegation in

jQuery before 1.7.

Event Delegation• .on()

• new in jQuery 1.7

• the future of jQuery event handling

• one event handler method to rule them all

• use instead of .bind() and .live() and .delegate()

• .off()

• unbinds event handlers bound by .on()

$('button').on('click', clickListener).on('click', otherListener);;

// remove all click listeners$('button').off('click');

// remove only the specified listener$('button').off('click', clickListener);

Direct Event Binding

$('#wrapper').on('click', 'button',function(event) {

// button got clicked});

// remove click listeners$('#wrapper').off('click', 'button');

Event Delegation

event object• normalized by jQuery to provide consistent information

across browsers

• event.target to access the element that triggered the event

• event.pageX/Y for mouse position

• event.preventDefault() to prevent an event's default action

• event.stopPropagation() to prevent an event from bubbling

• event.which to identify which key is pressed

• more event properties at

http://api.jquery.com/category/events/event-object/

$('a.toggler').on('click', function(event) {event.preventDefault();event.stopPropagation();

$(this).parent().next().slideToggle();

// or, return false to both // preventDefault and stopPropagation// (but problematic)

});

event object example• prevent the default action from occurring

• stop the event's propagation up the DOM

$('button').on('mouseenter mouseleave', function(event) {var isEntered = event.type == 'mouseenter';

$('#something').toggleClass('active-related', isEntered);

if (isEntered) {// do one thing

} else {// do another

}});

event object example• identify the type of event being triggered

event object

• Very useful for key events

• event.which : key code normalized by jQuery

• event.metaKey : command / ⌘ on Mac, control on Win

• event.altKey : alt / option / ⌥ on Mac

• event.ctrlKey : control key everywhere

• event.shiftKey

• key event demo

if (document.createTouch) {

$('body').bind('touchstart touchmove touchend', function(event) {

// use the original event:event = event.originalEvent;

// pass the first touch object as a second argumentvar touch = event.targetTouches[0];sideSwipe[ event.type ](event, touch);

});}

event object

• access newer event types through the original event

// declare some variables up here (startcoords, endcoords, etc.)

var sideSwipe = {touchstart: function(event, firstTouch) {

startcoords = {x: firstTouch.pageX, y: firstTouch.pageY};},touchmove: function(event, firstTouch) {

if (event.targetTouches.length === 1) {event.preventDefault();endcoords = {x: firstTouch.pageX, y: firstTouch.pageY};

} else {endcoords = startcoords;

}},touchend: function(event) {// direction of horizontal swipe?// also, far enough horiz, not too far vert.?// if so, do something

}};

what?• sideSwipe[ event.type ](event, touch);

var sideSwipe = {touchstart: function(event, firstTouch) { },touchmove: function(event, firstTouch) { },touchend: function(event) { }

};

// if event.type equals 'touchstart', then:

/*

sideSwipe.touchstart() == sideSwipe['touchstart']()

sideSwipe['touchstart']() == sideSwipe[event.type]()

*/

what?• sideSwipe[ event.type ](event, touch);

var myEvents = {focus: function() {

alert('focused!');},blur: function() {

alert('blurry!');}

};

$('input').on( myEvents );

Wait!

• There must be a better way...

• First argument for .on() and .bind() can accept a map of event

types and their handler functions

var sideSwipe = {'touchstart touchmove': function(event) {

event = event.originalEvent;var firstTouch = event.targetTouches[0];

if (event.type == 'touchstart') {startcoords = {x: firstTouch.pageX, y: firstTouch.pageY};return;

}

if (event.targetTouches.length === 1) {event.preventDefault();endcoords = {x: firstTouch.pageX, y: firstTouch.pageY};

} else {endcoords = startcoords;

}},touchend: function(event) {

// get direction of horizontal swipe// also, far enough horiz, not too far vert.?// if so, do something

}};

event map

if (document.createTouch) {

$(document.body).on(sideSwipe);

}

event map

var $foo = $('#foo');var karlClicks = function() { /*do something*/ };

$foo.on('mouseenter.karl', function() { /*do something*/ });$foo.on('click.karl', karlClicks);

$foo.on('click', function() { /* do something */ });

$foo.off('.karl'); // stop doing .karl things

• Namespace events to ease unbinding

• Especially nice in plugins

Namespacing events

Custom Events• Awesome for "evented" programming

• Set up a bunch of behaviors all in one place.

• Fire at will ( .trigger() )

$(document).on('start.game', myGameStartFn);

$(document).on('stop.game', myGameStopFn);

$(document).on('updateScore.game', function(event, data) {

$.ajax('/gameserver/', data);

$('#scoreboard .score').html( data.score );

});

$(document).on('updateBoard.game', function(event, data) {

if (data.killed) {

$(event.target).fadeOut(400, function() {

$(this).remove();

});

}

});

$('div.alien').on('click', function(event) {

score += 1000;

var data = {

score: score,

killed: this.className,

name: $(this).data('name')

};

$(this)

.trigger('updateBoard.game')

.trigger('updateScore.game', [data]);

if ( score > 1000000) {

$(document).trigger('stop.game');

}

});

Custom Events Fake Example

DOM Manipulation

• Create Elements

• Insert Elements

• Element Content

• Remove Elements

• Element Properties and Attributes

• Styles and Dimensions

DOM Manipulation

$('div')

$('<div></div>')

$('<div/>')

$('<div/>', {'class': 'test',html: '<b>Click me!</b>',click: function(){$(this).toggleClass('test');

}});

reserved word

$('<div/>', {'class': 'test',html: '<b>Click me!</b>',click: function(){$(this).toggleClass('test');

}}).appendTo('body');

• Clone elements via $('#myid').clone()

• .clone(true) to copy events and data, too

Clone Elements

• add and move elements

• inside others with .append(), .appendTo(), .prepend() and

.prependTo()

• before and after others with

.after(), .insertAfter(), .before() and .insertBefore()

• around others with .wrap(), .wrapAll() and .wrapInner()

• in place of others with .replaceWith() and .replaceAll()

Insert Elements(or move them)

• $('<div></div>').appendTo('#mydiv');

• $('#mydiv').append('<div></div>');

• $('<div></div>').insertAfter('#mydiv');

• $('#mydiv').after('<div></div>');

• // and so on

Insert Elements(or move them)

• In 1.4 and above, a subset of these methods can take a

function

• .append()

• .prepend()

• .after()

• .before()

• .wrap()

• .wrapInner()

• In the function, you'll need to return the content you want to

insert

Insert Elements(or move them)

• Remove elements with .remove()

• Cleans up data and events

• Remove elements with .detach()

• Leaves data and events alone

• Remove their content with .empty()

• Cleans up data and events

Remove Elements

• Get and set HTML content via .html()

• executes embedded JavaScript when setting

• Get and set text content via .text()

• escapes HTML entities (<, >, &)

• recursive (drills down / concatenates)

• Get and set form element values with .val()

Element Content

Attributes &

Properties• Get and set any property with .prop()

• Remove properties with .removeProp()

• Get and set any attribute with .attr()

• Remove attributes with .removeAttr()

Attributes &

Propertieswhat's the difference?• Attributes are what you see in the HTML.

• Properties are ... well ... properties of DOM elements (objects)

Attributes &

Propertieswhat's the difference?• Some props don't have attr equivalents

• Some props and attrs have different names

prop attrselectedIndex, tagName, nodeName,

nodeType, ownerDocumentnothing, nada, zilch,

nil, goose egg

htmlFor for

className class

Attributes &

Propertieswhat's the difference?• Some attributes are considered boolean attributes

• For these, you really ought to get and set with .prop()

• ... even though jQuery will still coddle you if you do it wrong

Attributes &

Propertieswhat's the difference?• <input type="checkbox" checked="checked">

• <script>

• // DOM property

• // Will change with checkbox state

• elem.checked == true;

• // Will change with checkbox state

• $(elem).prop("checked") == true;

• </script>

Attributes &

Propertieswhat's the difference?• <input type="checkbox" checked="checked">

• <script>

• // DOM method

• // Initial state of the checkbox; does not change

• elem.getAttribute("checked") == "checked";

• //(1.6) Initial state of the checkbox; does not change

• $(elem).attr("checked") == "checked";

• //(1.6.1+) Will change with checkbox state

• $(elem).attr("checked") == "checked";

Attributes &

Properties• See why you should use .prop() ?

• ( applies to "selected", too )

Attributes &

Properties• Remember me?

$('<div/>', {

'class': 'test'

});

• I use .attr() (so you must use "class", not "className")

$('a').attr('href');

Attributes

• get attribute:

$('input').attr({title: 'this is my title', name: 'some_name'

});

$('input').attr('title', 'this is my title');

Attributes

• set attribute:

$('img').attr({title: function(index, value) {return 'I do believe that ' + value;

}, name: 'some_name'

});

$('a').attr('title', function() {return 'go to ' + this.href;

});

Attributes

• set attribute:

$('a').prop('id'); $('a').prop('href'); // this one is problematic!

Properties

• get prop:

$('input').prop({title: 'this is my title', name: 'some_name'

});

$('input').prop('title', 'this is my title');

Properties

• set property:

$('img').prop({title: function(index, value) {return 'I do believe that ' + value;

}, name: 'some_name'

});

$('a').prop('title', function() {return 'go to ' + this.href;

});

Properties

• set property:

• Use .css() to modify the style property

• Use .addClass(), .removeClass() and .toggleClass() to modify

the class attribute

• When possible, manipulate the class attribute to change

appearance, separating the actual design from the behavior

Styles

Style Properties• get style property

• $('a').css('color');

$('a').css({backgroundColor: 'red', 'margin-top': '10px'

});

$('a').css('backgroundColor', 'red');

Style Properties• set style property

Notice!

either DOM

prop or CSS

syntax

$('a').css('fontSize', function() {

return parseInt($(this).css('fontSize'),10) + 2 + 'px';

});

$('a').css({

backgroundColor: 'red',

marginTop: function(index, value) {

return parseInt(value,10) * 1.4;

}

});

Style Properties• set style property:

• Get and set width and height via .width() and .height()

• return a number

• nice for calculations

• Get and set the element offset relative to the document with

.offset()

• returns an object

• e.g. {top: 34, left: 50}

• Get the element offset relative to its "offset parent" with

.position()

Dimensions

• associate data with elements

• plugin settings

• plugin instances

• avoid storing data directly on DOM elements

• avoid memory leaks

• Set data: $('div').data('personalInfo', {firstname:'karl'});

• Get data: $('div').data('personalInfo');

• Remove data: $('div').removeData('personalInfo');

Data

• As of jQuery 1.4.4, can read HTML5 data-* attributes.

• jQuery guesses what the type is and treats it accordingly.

• To parse a data value as an object, it must appear as

valid JSON.

• Read learningjquery.com/2011/09/using-jquerys-data-

apis

• <div data-img='{"alt":"pic","src":"path/file.jpg"}'>

</div>

• $('div').data('img');

Data

• and look at examples

Q & A

Ajax

Ajax

• Unobtrusive client-server data exchange

• avoid page refresh

• Affords much more interactive applications

• becoming nearly indistinguishable from desktop applications

• Progressive Enhancement is essential

$.ajax

• jQuery's low-level abstraction for Ajax

• all high-level methods build on it

• Configured per request or global defaults

$.ajax({url: '/url/to/serverResource'

});

$.ajax options: url

• Address of the server-side resource

• Can contain query string

• use data instead

$.ajax('/url/to/serverResource');

$.ajax options: url

• Address of the server-side resource

• Can be passed as a string to first argument (as of 1.5)

$.ajax({url: '/url/to/serverResource',data: {key1: 'value1',key2: 'value2'

}});

$.ajax options: data

• To send information from client to server

• with GET: Appended to url as query string

• with POST: Sent as POST body

$('#myform').submit(function(event) {event.preventDefault();

var formUrl = $(this).attr('action'),formData = $(this).serialize();

$.ajax({url: formUrl,data: formData

});

});

$.ajax options: data

• When submitting a form, use .serialize( )

$.ajax options:

dataType• 'html' for HTML to insert into document

• 'xml' for XML documents, eg. web services

• 'json' for compact alternative to XML

• parsed using browser's native JSON parser if available

• much easier to use in JS than XML

• 'jsonp' for remote resources. Gets around same-origin

policy.

• Response acts like a function with a JSON string as its

argument. jQuery calls it and parses the JSON.

• 'script' for JavaScript files

• Evaluates the response as JavaScript and returns it as

plain text.

$.ajax({url: '/url/to/serverResource',dataType: 'json'

});

$.ajax options:

dataType• Specifies expected response

• Default based on MIME Type of the response

$.ajax options:

Lots More• Read all about 'em at api.jquery.com/jQuery.ajax/

$.ajaxSetup( )

• Global ajax settings

$.ajax({

url: '/url/to/serverResource',

success: function(response, status, xhr) {

// do something after successful request

},

error: function(xhr, status, errorThrown) {

// handle failed request

},

complete: function(xhr, status) {

// do something whether success or error

}

});

$.ajax responses• Before jQuery 1.5, these were handled by three more options (!!)

• { success: function(){}, error: function(){}, complete:

function(){} }

• don't use them anymore

Ajax error handling

• Explicit testing for ajax errors is important

• Network failures don't occur in local development

environment

• p.s. JSON parsing errors throw an exception

$.ajax responses• $.ajax implements the Promise interface

• returns a jqXHR object (superset of xhr), a Promise

• Promise objects are derived from the Deferred object

• Not enough time to dive into that today

• Read api.jquery.com/category/deferred-object/

• jQuery 1.5+:

• .done() and .fail() methods

• jQuery 1.6+:

• .always() method

$.ajax responses1.5+

• Methods can be called multiple times to add more than one

handler.

• Can store result of Ajax request in variable and attach handlers

later for more manageable code structure.

• Handlers will be invoked immediately if the Ajax operation is

already complete when they are attached

• Ajax requests can be cached in a simple, elegant way

$.ajax responses1.5+• var myOptions = {

• url: 'http://api.jquery.com/jsonp/',

• dataType: 'jsonp',

• data: {

• title: search

• }

• };

• $.ajax( myOptions )

• .done( successFn )

• .fail( errorFn )

• .always( completeFn );

request.done(successFnA, successFnB, successFnC);

request.done([successFnD, successFnE, successFnF]);

request.done(successFnG).done(successFnH).done(successFnJ);

$.ajax responses1.5+

• Multiple function arguments

• Array of functions

• Multiple, chained .done() methods

Caching Ajax

Responses• A simple approach

• For more generic, abstracted approach, see Script Junkie:

"Creating Responsive Applications Using jQuery Deferred and

Promises" bit.ly/tph6F6

Caching Ajax

Responses• (function() {

• var api = {}, $response = $('#response');

• $('#ajaxForm').bind('submit', function(event) {

• event.preventDefault();

• var search = $('#title').val();

• $response.empty().addClass('loading');

Caching Ajax

Responses• (function() {

• var api = {}, $response = $('#response');

• $('#ajaxForm').bind('submit', function(event) {

• event.preventDefault();

• var search = $('#title').val();

• $response.empty().addClass('loading');

• var ajaxResults = $.ajax({

• url: 'http://api.jquery.com/jsonp/',

• dataType: 'jsonp',

• data: {

• title: search

• },

• timeout: 15000

• });

Caching Ajax

Responses• (function() {

• var api = {}, $response = $('#response');

• $('#ajaxForm').bind('submit', function(event) {

• event.preventDefault();

• var search = $('#title').val();

• $response.empty().addClass('loading');

• api[search] = $.ajax({

• url: 'http://api.jquery.com/jsonp/',

• dataType: 'jsonp',

• data: {

• title: search

• },

• timeout: 15000

• });

Caching Ajax

Responses• (function() {

• var api = {}, $response = $('#response');

• $('#ajaxForm').bind('submit', function(event) {

• event.preventDefault();

• var search = $('#title').val();

• $response.empty().addClass('loading');

• if (!api[search]) {

• api[search] = $.ajax({

• url: 'http://api.jquery.com/jsonp/',

• dataType: 'jsonp',

• data: {

• title: search

• },

• timeout: 15000

• });

Caching Ajax

Responses• (function() {

• var api = {}, $response = $('#response');

• $('#ajaxForm').bind('submit', function(event) {

• event.preventDefault();

• var search = $('#title').val();

• $response.empty().addClass('loading');

• if (!api[search]) {

• api[search] = $.ajax({

• url: 'http://api.jquery.com/jsonp/',

• dataType: 'jsonp',

• data: {

• title: search

• },

• timeout: 15000

• });

Ajax Convenience

Methods• $.get()

• $.post()

• $.getJSON()

• $.getScript()

$('#myid').load('/foo.html #anotherid');

$('#myid').load('/foo.html #anotherid', function() {// do something on complete

});

Ajax Convenience

Methods• $('elem').load( )

• The "convenientest" of all …

• Single argument can do it all. Often no need for callback

function.

Ajax Convenience

Methods• My recommendation:

• Use $.ajax()

Effects

• Slides

• Fades

• Custom animations

Introduction

• Effects can enhance user interaction

• Prefer subtle over in-your-face

• jQuery provides a base set of animations

• make animations:

• long enough to be noticeable

• short enough to not annoy

Fades• great to show/hide overlay elements

• tooltips

• dialogs

• warning/info messages

• Examples:

• $('.tooltip').fadeIn();

• $('.tooltip').fadeOut('slow');

• $('.tooltip').fadeToggle(250);

• $('.tooltip').fadeTo(200, 0.5);

$('div.panel').wrapAll('<div class="panel-wrapper"></div>');

$('div.panel-heading a').click(function() {$(this).parent().next('.panel-wrapper').slideToggle();return false;

});

Slides

• show and hide elements within the page structure

• less jarring than un-animated show/hide

$('div.toRemove').slideUp('slow', function() {$(this).remove();

});

$('div.move').slideDown(250).promise().done(function() {alert('Finished!');

});

Callback

• Function executed when the animation ends

• Called once for each animated element

• Consider using .promise()

Animation Order

• By default multiple animations occur:

• in sequence for the same element(s)

• simultaneously for different element(s)

Custom Animations

• $('div.toMove').animate(propsObject, duration, easing, callbackFn);

• $('div.toMove').animate(propsObject, optionsObject);

• Properties can be animated

• by number, percent, etc.

• relatively ("+=200px", "-=20%", etc.)

• by keyword: "hide", "show", or "toggle"

$('.toMove').animate({left: '+=300px'

}, 800);

// same thing$('.toMove').animate({

left: '+=300px'}, {

duration: 800});

Custom Animations

• Create custom animations

• Example, slowly moving an element 300px to the right:

Custom Animations• Options object allows for fine tuning:

• duration: A string or number determining how long the animation will run.

• easing: A string indicating which easing function to use for the transition.

("linear", "swing". More with plugin.)

• complete: A function to call once the animation is complete. (callback

function.)

• step: A function to be called after each step of the animation.

• queue: A Boolean indicating whether to place the animation in the effects

queue. If false, the animation will begin immediately.

• specialEasing: A map of one or more of the CSS properties defined by the

properties argument and their corresponding easing functions (added 1.4).

$('#foo').animate({height: 'toggle'}, {

duration: 600,

easing: 'linear'

});

Easing

• Changes the velocity at different points in the animation

• A number of standard equations first created by Robert Penner

• Available with jQuery UI

• Also, stand-alone at http://gsgd.co.uk/sandbox/jquery/easing/

$('#clickme').click(function() {$('#book').animate({

width: ['toggle', 'swing'],height: ['toggle', 'swing'],opacity: 'toggle'

}, 5000, 'linear', function() {$(this).after('<div>complete!</div>');

});});

Easing

• Per-property easing available as of jQuery 1.4.

$('.toMove').click(function() {if (!$(this).is(':animated')) {

$(this).animate({left: '+=300px'

}, 'slow');}

});

Currently Animated

• Identify elements that are currently animated

$('#badges li').hover(function(){$(this).stop(true,

true)

.animate({bottom:"30px"}, 200);},

function(){$(this).stop(true, false)

.animate({bottom:"8px"}, 500);});

Stop

• Stop current animations from continuing.

• Two arguments: clearQueue and gotoEnd (both boolean)

A Quick Example

• LittleOrangeStar.com

$('#warning').fadeIn(600).delay(4000).fadeOut();

Delay

• Delays any further items in the queue from executing for a

specified period of time.

// animation will complete in 400ms$('#foo').slideToggle();

// modify default globally for all future effects$.fx.speeds._default = 250;

// animation will complete in 250ms$('#foo').slideToggle();

Global Duration

• Globally change the duration that all animations will use unless

a duration is specified.

$('.animations').click(function() {

$.fx.off = !$.fx.off;

});

Global Off

• Globally prevent all animations from occurring

Thank You