Transcript Slide 1

JavaScript 101: Adding Interactivity to
Your Site With the World’s Most Popular
Programming Language*
Rob Larsen
1.28.2010
htmlcssjavascript.com | drunkenfist.com
@robreact
htmlcssjavascript.com/downloads/javascript.ppt
*Douglas Crockford http://javascript.crockford.com/popular.html
Who is this Guy Anyway?
• 12+ years HTML/CSS/JavaScript. My day
job since 1999.
• For one more day: Principal Presentation
Engineer at Cramer
• Next Week: Molecular
•
PAST: AdvisorTech, Compete, Demandware, The Weekly Dig, Gillette, Museum of
Science, Boston, PC Connection, State Street, Webex
What Are We Going To Talk
About
We’re going to walk, step by step, through adding some
simple interactivity to a web page using JavaScript.
There will be three levels for every step:
• For beginners “this is how you do it”
• For intermediate “this is why we do it this way”
• For advanced users we’ll touch on some details/enhancements/cool stuff
The Basic Idea
I get a lot of Google Traffic along the lines of
“how to include javascript in html”
I’m working on a series of blog posts. The hope
is to document the way I go about making web
sites.
Tonight we’re skipping ahead to the JavaScript
section.
The Sample Page
I Told You This Was a Work in
Progress
The Basic Concepts
•
•
•
•
•
HTML + CSS + JavaScript
Content + Style + Behavior
As fast as possible (by default)
Make as much sense as possible
+ A Bunch of Other Stuff Outside of
Tonight’s Scope (accessibility, findability,
usability, etc)
Starter Assets
• http://code.google.com/p/starter-assets/
JavaScript
• “JavaScript is an object-oriented scripting
language used to enable programmatic
access to objects within both the client
application and other applications. It is
primarily used in the form of client-side
JavaScript, implemented as an integrated
component of the web browser, allowing the
development of enhanced user interfaces
and dynamic websites. JavaScript is a dialect
of the ECMAScript standard and is
characterized as a dynamic, weakly typed,
prototype-based language with first-class
functions.
”
[wikipedia]
The Important Bits (that you need
to worry about right now)
• Weakly Typed
console.log("4" * "5")
20
• Functions are first class Objects
doStuff(function(){
var someObject = doSomeOtherStuff();
return someObject;
})
Let’s Do This
Let’s get the script on the page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Let's Make a Web Page</title>
<link href="_assets/styles/screen.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<div id="header">
<h1>Let's Make a Web Page </h1>
</div>
<div id="main">
<div id="sidebar">
<ul>
<li><a href="http://twitter.com/" id="make-it-so">Show Tweets</a></li>
</ul>
</div>
<div id="ads">This is an ad</div>
<div id="content">
<h1>H1 Header for topics Lorem Ipsum Dolor Sit Amet, Consector Adipiscing </h1>
<div id="twitter">
<!--your tweets here-->
</div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. <a
href="#">&lt;a&gt; Link treatment urna nibh</a>, viverra non, semper suscipit, posuere a, pede. <abbr title="ABBR">&lt;abbr&gt;</abbr> or
<!—snip
</div>
</div>
<div id="footer">Released Under the The MIT License. Copyright (c) 2010 Rob Larsen</div>
</div>
<script type="text/javascript" src="_assets/scripts/demo.js"></script>
</body>
</html>
Your own script
Let’s get the script on the page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Let's Make a Web Page</title>
<link href="_assets/styles/screen.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<div id="header">
<h1>Let's Make a Web Page </h1>
</div>
<div id="main">
<div id="sidebar">
<ul>
<li><a href="http://twitter.com/" id="make-it-so">Show Tweets</a></li>
</ul>
</div>
<div id="ads">This is an ad</div>
<div id="content">
<h1>H1 Header for topics Lorem Ipsum Dolor Sit Amet, Consector Adipiscing </h1>
<div id="twitter">
<!--your tweets here-->
</div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. <a
href="#">&lt;a&gt; Link treatment urna nibh</a>, viverra non, semper suscipit, posuere a, pede. <abbr title="ABBR">&lt;abbr&gt;</abbr> or
<!—snip
</div>
</div>
<div id="footer">Released Under the The MIT License. Copyright (c) 2010 Rob Larsen</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="_assets/scripts/demo.js"></script>
</body>
</html>
jQuery
What’s Up With That?
Why do we put the script at the bottom?
• “The problem caused by scripts is that they block parallel
downloads. The HTTP/1.1 specification suggests that
browsers download no more than two components in
parallel per hostname. If you serve your images from
multiple hostnames, you can get more than two
downloads to occur in parallel. While a script is
downloading, however, the browser won't start any other
downloads, even on different hostnames. ”
•
http://developer.yahoo.com/performance/rules.html#js_bottom
While The Previous is Good, It Can
Be Made Better
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Let's Make a Web Page</title>
<link href="_assets/styles/screen.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<div id="header">
<h1>Let's Make a Web Page </h1>
</div>
<div id="main">
<div id="sidebar">
<ul>
<li><a href="http://twitter.com/" id="make-it-so">Show Tweets</a></li>
</ul>
</div>
<div id="ads">This is an ad</div>
<div id="content">
<h1>H1 Header for topics Lorem Ipsum Dolor Sit Amet, Consector Adipiscing </h1>
<div id="twitter">
<!--your tweets here-->
</div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. <a
href="#">&lt;a&gt; Link treatment urna nibh</a>, viverra non, semper suscipit, posuere a, pede. <abbr title="ABBR">&lt;abbr&gt;</abbr> or
<!—snip
</div>
</div>
<div id="footer">Released Under the The MIT License. Copyright (c) 2010 Rob Larsen</div>
</div>
<script type="text/javascript" src=“http://cdn.example.com/_assets/scripts/demo.min.0001.js"></script>
</body>
</html>
One scripts file. Served off site CDN or other non-cookied domain. Minified and gzipped.
Why’s That Better? It looks like
the first example.
Two script files (jQuery + application code) minified and
combined into one.
1 less download.
1 less DNS lookup.
Minfication/gzipping reduces file size significantly.
There are plugins/libraries/whatevers out there that can
help you concatenate scripts. Or, of course, you can also
do it manually.
YUI is Awesome
<!-- Combo-handled YUI JS files: --> <script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.0r4/build/yuiloader-domevent/yuiloader-dom-event.js&2.8.0r4/build/selector/selector-min.js&2.8.0r4/build/event-delegate/event-delegate-min.js&2.8.0r4/build/eventmouseenter/event-mouseenter-min.js&2.8.0r4/build/element/element-min.js&2.8.0r4/build/element-delegate/element-delegatemin.js&2.8.0r4/build/event-simulate/event-simulate-min.js&2.8.0r4/build/cookie/cookie-min.js&2.8.0r4/build/storage/storage-min.js"></script>
http://developer.yahoo.com/yui/articles/hosting/
Minified?
function writeTwitterSearchResults(obj) {
if ($("#twitter-list")) {
$("#twitter-list").remove();
}
$("#twitter").append("<ul id='twitter-list'></ul>");
var user, text;
var test = obj.results.length;
for (var i=0; i<test; i++) {
if(i % 2) {
theClass="even";
} else {
theClass="odd"
};
text = obj.results[i].text;
console.log(text);
text=text.replace(/(http\:\/\/[\S]*)/g,"<a href='$1'>$1</a> ");
console.log(text);
text=text.replace(/(@)([\S]*)(\s)/g,"<a href='http://twitter.com/$2'>$1$2$3</a> ")
console.log(text);
user = obj.results[i].from_user;
$("#twitter-list").append("<li style='backgroundimage:url("+obj.results[i].profile_image_url+")' class='"+theClass+"' ><a href='http://twitter.com/" + user +
"'>" + user + ":</a> " + text +"<span class='time'>"+ obj.results[i].created_at +"GMT</span></li>" )
};
};
http://yui.2clics.net/
Minified?
function writeTwitterSearchResults(obj){if($("#twitter-list")){$("#twitter-list").remove();}$("#twitter").append("<ul id='twitter-list'></ul>");var
user,text;var test=obj.results.length;for(var
i=0;i<test;i++){if(i%2){theClass="even";}else{theClass="odd";}text=obj.results[i].text;console.log(text);text=text.replace(/(http\:\/\/[\S]*)/g,"<a
href='$1'>$1</a> ");console.log(text);text=text.replace(/(@)([\S]*)(\s)/g,"<a href='http://twitter.com/$2'>$1$2$3</a>
");console.log(text);user=obj.results[i].from_user;$("#twitter-list").append("<li style='background-image:url("+obj.results[i].profile_image_url+")'
class='"+theClass+"' ><a href='http://twitter.com/"+user+"'>"+user+":</a> "+text+"<span
class='time'>"+obj.results[i].created_at+"GMT</span></li>");}}
//14% savings. Gzip is much more importnt.
http://yui.2clics.net/
Let’s Get the Script on the Page
Where does this fall apart?
HTML5, Scope
Anyone Using Any Advanced Techniques?
Maybe some of the kind of stuff this guy wrote about in his book?
Initialize
$(document).ready( function() {
$("#make-it-so").click(results);
}
);
jQuery
Initialize
function init() {
document.getElementById("make-it-so").addEventListener("click" , results, false);
}
window.addEventListener("DOMContentLoaded", init, false);
Raw JS
Initialize
We want to keep out behavior out of our content.
To do that we create a function init contains all of the
instructions we want to run when the page loads.
We set that function to run when the DOM is loaded.
It attaches an event to an element with the id “make-it-so”
DOM?
The Document Object Model (DOM) is a cross-platform
and language-independent convention for representing and
interacting with objects in HTML, XHTML and XML
documents (wikipedia again)
It’s the framework within which we interact with stuff on the
page.
In this sense, I’m using the DOM to refer to all of the
markup (content) on the page. Once that’s done
downloading, the browser sets up the DOM framework. We
can then work with it in a predictable manner.
Why Do We Care When the
DOM is Loaded?
We want to change the page as soon as possible, but not
too soon. This moment when the DOM is loaded is the
sweet spot for that manipulation
Let’s Take a Quick Look at the
Function
function results(e) {
var twitterJSON = document.createElement("script");
twitterJSON.type="text/javascript";
twitterJSON.src="_assets/scripts/search.json";
document.body.appendChild(twitterJSON);
e.preventDefault();
};
function writeTwitterSearchResults(obj) {
var twitterDIV = document.getElementById("twitter");
if (document.getElementById("twitter-list")) {
twitterDIV.innerHTML="";
}
var twitterUL = document.createElement("UL");
twitterUL.setAttribute("id","twitter-list");
var user, text, test = obj.results.length, twitterSPAN, twitterA, twitterLI;
for (var i=0; i<test; i++) {
twitterSPAN = document.createElement("SPAN");
twitterA = document.createElement("A");
twitterLI = document.createElement("LI");
//continued
Raw JS
Let’s Take a Quick Look at the
Function
if(i % 2) {
twitterLI.className="even";
};
text = obj.results[i].text;
text=text.replace(/(http\:\/\/[\S]*)/g,"<a href='$1'>$1</a> ");
text=text.replace(/(@)([\S]*)(\s)/g,"<a href='http://twitter.com/$2'>$1$2$3</a> ")
user = obj.results[i].from_user;
twitterLI.style.backgroundImage="url('"+obj.results[i].profile_image_url+"')"
twitterA.href= "http://twitter.com/"+user;
twitterA.appendChild(document.createTextNode(user+":"));
twitterSPAN.appendChild(document.createTextNode(obj.results[i].created_at+" GMT"));
twitterSPAN.className="time";
twitterLI.appendChild(twitterA);
twitterLI.innerHTML+= " "+text;
twitterLI.appendChild(twitterSPAN);
twitterUL.appendChild(twitterLI);
};
twitterDIV.appendChild(twitterUL);
};
Raw JS
Let’s Take a Quick Look at the
Function
function results(e) {
$.getJSON("http://search.twitter.com/search.json?q=javascript&amp;count=10&callback=?",
writeTwitterSearchResults );
e.preventDefault();
};
function writeTwitterSearchResults(obj) {
if ($("#twitter-list")) {
$("#twitter-list").remove();
}
$("#twitter").append("<ul id='twitter-list'></ul>");
var user, text;
var test = obj.results.length;
for (var i=0; i<test; i++) {
if(i % 2) {
theClass="even";
} else {
theClass="odd"
};
text = obj.results[i].text;
text=text.replace(/(http\:\/\/[\S]*)/g,"<a href='$1'>$1</a> ");
text=text.replace(/(@)([\S]*)(\s)/g,"<a href='http://twitter.com/$2'>$1$2$3</a> ")
user = obj.results[i].from_user;
$("#twitter-list").append("<li style='background-image:url("+obj.results[i].profile_image_url+")'
class='"+theClass+"' ><a href='http://twitter.com/" + user + "'>" + user + ":</a> " + text +"<span class='time'>"+
obj.results[i].created_at +"GMT</span></li>" )
};
};
jQuery
Testing/Debugging
We’ve come in from the wilderness. Back in my day we had
to walk both directions, uphill in the snow.
console.log(“rocks”)
FireBug (f12)
Console
FireBug
DOM Inspector
FireBug
Breakpoints
Safari (ctrl +alt + i)
Internet Explorer 8 (f12)
Chrome (ctrl + shft + j)
Advanced Tools?
Unit Testing?
Testing Automation?
Any Questions?
More Info
•
•
•
•
•
•
•
•
http://javascript.crockford.com/
http://ejohn.org/apps/learn/
http://api.jquery.com/
http://www.quirksmode.org/
http://www.nczonline.net/
http://www.alistapart.com/articles/behavioralseparation
http://yui.2clics.net/
http://www.stevesouders.com/blog/2009/04/27/loading
-scripts-without-blocking/
• http://developer.yahoo.com/performance/
• http://developer.yahoo.com/yui/articles/hosting/