Harvard Extension School, Fall 2018
CSCI E-12 Fundamentals of Web Site Development

# Session 08 - JavaScript, Part 1

Harvard Extension School
Fall 2018

Course Web Site: http://cscie12.dce.harvard.edu/

Instructor email: david_heitmeyer@harvard.edu
Course staff email: cscie12@dce.harvard.edu

### Topics

1. JavaScript
2. First Javascript Example and "click" event
3. Events and Event Attributes
4. JavaScript and HTML
5. JavaScript and Forms
6. Document Object Model (DOM)
7. Table striping with Javascript
8. Things will go wrong...the Javascript Console is your friend
9. Your Work Easier with JavaScript Libraries
10. jQuery Plugin - Tablesorter
11. Separation from Markup
12. Minified JS

slide1 slide2 slide3 slide4 slide5 slide6 slide7 slide8 slide9 slide10 slide11 slide12 slide13 slide14 slide15 slide16 slide17 slide18 slide19 slide20 slide21 slide22 slide23 slide24 slide25 slide26 slide27 slide28 slide29 slide30 slide31 slide32 slide33 slide34 slide35 slide36 slide37 slide38 slide39 slide40 slide41

- img
- img
- img
- img
- img

## JavaScript

Goals for the JavaScript Unit

- Understand basics of JavaScript
  - events
  - console
- Understand basics of jQuery
- Understand how to use JavaScript
  - Separate JS from Markup
  - Be able to incorporate JavaScript functionality into a site
  - Be able to "hack" JavaScript and jQuery to find solutions
- Ready for more!

## Client-side Web Parts: Markup, Style, Function

Markup (HTML) Structure Content Style (CSS) Style Presentation Appearance Function (JavaScript) Actions Manipulations | Structure + Style + Function: solarsystem.html Structure + Style: solarsystem-style.html Structure: solarsystem-markup.html

Files:

- solarsystem.css
- jquery-1.4.2.min.js
- jquery.mousewheel-3.0.2.pack.js
- jquery.fancybox-1.3.1.js
- jquery.fancybox-1.3.1.css
- fancybox.png
- fancybox-x.png
- fancybox-y.png
- blank.gif

Files:

- solarsystem.css
- jquery.js
- thickbox.css
- thickbox-uncompressed.js
- loadingAnimation.gif
- macFFBgHack.png

## Javascript

"JavaScript is now a language every developer should know."
– Mike Loukides, Vice President of Content Strategy for O'Reilly Media

JavaScript is everywhere: servers, rich web client libraries, HTML5, databases, even JavaScript-based languages. If you've avoided JavaScript, this is the year to learn it. And if you don't, you risk being left behind.

### What is it?

- Programming language
- Runs within web browser
- Browser runs Javascript based upon events
- [Server-side language as well!]

### What can it do?

Javascript provides programmatic access to virtually all aspects of a page.

- CSS properties
- Markup content
- Forms, communication to Server
- Add functionality

## Javascript Resources

- JavaScript - Mozilla Developer Center
- JavaScript Tutorial and Reference from w3schools.com

### jQuery

- jQuery Learning Center
- How jQuery Works

## Javascript: Manipulate Styles

- Manipulate Styles
- Manipulate Content
- Communicate with Web Server (Ajax)
- Add functionality

## Javascript: Manipulate Content

- Manipulate Styles
- Manipulate Content
- Communicate with Web Server (Ajax)
- Add functionality

## Javascript: Communicate with Web Server (Ajax)

- Manipulate Styles
- Manipulate Content
- Communicate with Web Server (Ajax)
- Add functionality

## Javascript: Add functionality

- Manipulate Styles
- Manipulate Content
- Communicate with Web Server (Ajax)
- Add functionality

## Events

- Events - things that happen on page
- Event Handlers - code that is run when an event happens
- Registering an Event Handler - linking the code you want to run to an event

### Events

- click
- change
- submit
- load
- mouseover
- mouseout
- focus
- blur
- select
- dblclick
- keydown
- keyup
- keypress
- unload
- mousedown
- mousemove
- mouseup
- reset

## ECMAScript and JavaScript

The standard for JavaScript is called ECMAScript.

- ECMAScript v 5 (2009) and 5.1 (2011)
- ECMAScript v 6 (2015) -- you'll also see this as "ES6".

## First Javascript Example and "click" event

`onclick="document.getElementById('simple1a').style.backgroundColor='#ff33ff';"`

- "onclick" event attribute
- Javascript:
  `document.getElementById('simple1a').style.backgroundColor='#ff33ff';`
  - `document` - the web page loaded in the browser
  - `getElementById('simple1a')` - finds the element based upon the value of the "`id`" attribute (`id="simple1a"`)
  - `style` - the style properties of an element
  - `backgroundColor='#ff33ff'` - assigns the 'background-color' style property to the given value

Example 8.1 - Javascript Events Illustrated - Example 8.1 (Without Styles) | <p><a href="#" onclick="document.getElementById('simple1a').style.backgroundColor='#ff33ff';">Change background color</a></p><p id="simple1a">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #simple1a { padding: 1em; border: medium solid black; width: 75%; }

- Markup
- Style
- Display

    <p><a href="#" onclick="document.getElementById('simple1a').style.backgroundColor='#ff33ff';">Change background color</a></p>
    <p id="simple1a">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #simple1a {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

Change background color

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.

## Second Javascript Example

- event attribute ("onclick")
- Javascript function

      function setBackgroundColor() {
          document.getElementById('simple1b').style.backgroundColor = '#ff33ff';
      }

- DOM function: getElementById

Example 8.2 - Javascript Events Illustrated - Example 8.2 (Without Styles) | <p><a href="#" onclick="setBackgroundColor();">Change background color</a></p><p id="simple1b">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #simple1b { padding: 1em; border: medium solid black; width: 75%; } function setBackgroundColor() { document.getElementById('simple1b').style.backgroundColor = '#ff33ff'; }

- Markup
- Style
- Script

    <p><a href="#" onclick="setBackgroundColor();">Change background color</a></p>
    <p id="simple1b">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #simple1b {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function setBackgroundColor() {
        document.getElementById('simple1b').style.backgroundColor = '#ff33ff';
    }

## Making setBackgroundColor function more generic

### Take 0

    function setBackgroundColor() {
        document.getElementById('simple2').style.backgroundColor = '#ff33ff';
    }

### Take 1

Two steps.

    function setBackgroundColor() {
        mynode = document.getElementById('simple2');
        mynode.style.backgroundColor = '#ff33ff';
    }

### Take 2

Two steps. Using variables to define "id" and color.

    function setBackgroundColor() {
        var myid = 'simple2';
        var mycolor = '#ff33ff';
        mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
    }

Example 8.3 - Javascript Events Illustrated - Example 8.3 (Without Styles) | <p><a href="#" onclick="setBackgroundColor();">Change background color</a></p><p id="simple2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #simple2 { padding: 1em; border: medium solid black; width: 75%; } function setBackgroundColor() { myid = 'simple2'; mycolor = '#ff33ff'; mynode = document.getElementById(myid); mynode.style.backgroundColor = mycolor; }

- Markup
- Style
- Script

    <p><a href="#" onclick="setBackgroundColor();">Change background color</a></p>
    <p id="simple2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #simple2 {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function setBackgroundColor() {
        myid = 'simple2';
        mycolor = '#ff33ff';
        mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
    }

## Making setBackgroundColor function more generic

### Take 2

Two steps. Using variables to define "id" and color.

    function setBackgroundColor() {
        var myid = 'simple2';
        var mycolor = '#ff33ff';
        var mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
    }

### Take 3

Passing in values for "id" and "color" when calling the function.

    function setBackgroundColor(myid,mycolor) {
        mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
    }

Example 8.4 - Javascript Events Illustrated - Example 8.4 (Without Styles) | <p><a href="#" onclick="setBackgroundColor('simple3','#33ffff');">Change background color</a></p><p id="simple3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #simple3 { padding: 1em; border: medium solid black; width: 75%; } function setBackgroundColor(myid,mycolor) { mynode = document.getElementById(myid); mynode.style.backgroundColor = mycolor; }

- Markup
- Style
- Script

    <p><a href="#" onclick="setBackgroundColor('simple3','#33ffff');">Change background color</a></p>
    <p id="simple3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #simple3 {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function setBackgroundColor(myid,mycolor) {
        mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
    }

## Allow User Input

- input text field:
  `<input type="text" id="background_color" />`
- Get the value: `.value`

Example 8.5 - Javascript Events Illustrated - Example 8.5 (Without Styles) | <p>Background color: <input type="text" id="background_color"/><br/><button onclick="setBackgroundColor('simple4');" type="submit">Set background color</button></p><p id="simple4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #simple4 { padding: 1em; border: medium solid black; width: 75%; } function setBackgroundColor(myid) { mynode = document.getElementById(myid); mycolor = document.getElementById('background_color').value; mynode.style.backgroundColor = mycolor; }

- Markup
- Style
- Script

    <p>Background color:
    <input type="text" id="background_color"/><br/><button onclick="setBackgroundColor('simple4');" type="submit">Set background color</button></p>
    <p id="simple4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #simple4 {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function setBackgroundColor(myid) {
        mynode = document.getElementById(myid);
        mycolor = document.getElementById('background_color').value;
        mynode.style.backgroundColor = mycolor;
    }

## Events and Event Attributes

Event | Event Attribute
--- | ---
click | onclick
change | onchange
submit | onsubmit
load | onload
mouseover | onmouseover
mouseout | onmouseout
focus | onfocus
blur | onblur
select | onselect
dblclick | ondblclick
keydown | onkeydown
keyup | onkeyup
keypress | onkeypress
unload | onunload
mousedown | onmousedown
mousemove | onmousemove
mouseup | onmouseup
reset | onreset

## Some Events Illustrated

- event attributes
- Javascript function

      function setBackgroundColor(myid,mycolor) {
          mynode = document.getElementById(myid);
          mynode.style.backgroundColor = mycolor;
      }

Example 8.6 - Javascript Events Illustrated - Example 8.6 (Without Styles) | <ul><li><a href="#" onclick="setBackgroundColor('p1','#ff3333');">Click to make "red"</a></li><li><a href="#" onclick="setBackgroundColor('p1','#3333ff');">Click to make "blue"</a></li><li><a href="#" ondblclick="setBackgroundColor('p1','#33ff33');">Double Click to make "green"</a></li><li><a href="#" onmouseover="setBackgroundColor('p1','#ffff33');" onmouseout="setBackgroundColor('p1','#cccccc');">Mouseover to make "yellow" and mouseout to make "gray"</a></li><li><a href="#" onkeypress="setBackgroundColor('p1','#ff33ff');">Keypress to make "magenta"</a></li></ul><p id="p1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem. </p> body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;} #p1 { padding: 1em; border: medium solid black; width: 75%; } function setBackgroundColor(myid,mycolor) { mynode = document.getElementById(myid); mynode.style.backgroundColor = mycolor; return false; }

- Markup
- Style
- Script
- Screenshot

     <ul>
    <li><a href="#" onclick="setBackgroundColor('p1','#ff3333');">Click to make "red"</a></li>
    <li><a href="#" onclick="setBackgroundColor('p1','#3333ff');">Click to make "blue"</a></li>
    <li><a href="#" ondblclick="setBackgroundColor('p1','#33ff33');">Double Click to make "green"</a></li>
    <li><a href="#" onmouseover="setBackgroundColor('p1','#ffff33');" onmouseout="setBackgroundColor('p1','#cccccc');">Mouseover to make "yellow" and mouseout to make "gray"</a></li>
    <li><a href="#" onkeypress="setBackgroundColor('p1','#ff33ff');">Keypress to make "magenta"</a></li>
    </ul><p id="p1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lobortis orci a odio. Donec cursus, felis eu pulvinar ornare, sem turpis dapibus elit, eget laoreet eros quam vel dolor. Ut ante mauris, ullamcorper quis, posuere quis, lacinia a, felis. In tincidunt malesuada pede. Donec varius lacus sed nisi. Donec rhoncus est ac erat. Duis lobortis fringilla eros. Donec volutpat ligula eu neque. In hac habitasse platea dictumst. Donec in massa. Aenean lectus ante, gravida et, luctus id, posuere at, pede. Nam risus orci, rhoncus eu, aliquam ut, interdum ut, orci. Suspendisse rutrum, turpis sed molestie gravida, libero risus iaculis ligula, quis tempor ligula enim vel sem.</p>

In `style` element (`<style type="text/css">`) within `head` element:

    body {font-family: Calibri,Tahoma,Verdana,Helvetica,sans-serif;}
    #p1 {
      padding: 1em;
      border: medium solid black;
      width: 75%;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function setBackgroundColor(myid,mycolor) {
        mynode = document.getElementById(myid);
        mynode.style.backgroundColor = mycolor;
        return false;
    }

## JavaScript and HTML

- Scripting (HTML Living Standard)
- `<script>` element
  - Can reference an external JS file (`src` attribute)
  - JS code can be within `script` element
- `<script>` element can go in `head`, but is often placed just before the body close (i.e. `</body>`) elements.
- Note the `<noscript>` element for clients without JavaScript.

## Script element in HTML/XML syntax should have separate end tag!

To function in all browsers, `script` element should have an explicit end tag. Best:

    <script src="jquery.js" type="text/javascript" > </script>

Do not use:

    <script src="jquery.js" type="text/javascript" />

## JavaScript in HTML

External Script

      <script src="path/to/javascript/file.js" type="text/javascript" > </script>

Script within HTML document

      <script type="text/javascript">
       /*
         JavaScript code as content of script element
       */
      </script>

"Inline" scripts as values of event attributes (Avoid!)

      <a href="#"
        onclick="javascript:void(window.resizeTo(1024,768))">
        Size Window to 1024 x 768
      </a>

## JavaScript and Forms

### Exposing Additional Form Elements

Additional relevant form elements are exposed based upon user input. Here, this is achieved by having the entire form in the markup, with a certain section hidden via CSS (`display: none;`). If "Yes" is chosen, the display property is changed to "block" through JS.

Example 8.7 - Exposing Additional Form Elements - Example 8.7 (Without Styles) | <form method="get" name="ice_cream" id="ice_cream" action="http://cscie12.dce.harvard.edu/echo" enctype="application/x-www-form-urlencoded"><div> Would you like ice cream?<br/><input type="radio" name="want" id="ic_yes" value="yes" onclick="displayIceCreamOptions()"/><label for="ic_yes">Yes</label><br/><input type="radio" name="want" id="ic_no" value="no" onclick="displayIceCreamOptions()"/><label for="ic_no">No</label></div><fieldset id="icecream_options" style="display: none;"><legend>Ice Cream Options</legend><p>How would you like it?</p><input type="radio" id="container_cup" name="container" value="cup"/><label for="container_cup">Cup</label><br/><input type="radio" id="container_cone" name="container" value="cone"/><label for="container_cone">Cone</label><br/><p>Pick your toppings:</p><input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/><label for="toppings_wc">Whipped cream</label><br/><input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/><label for="toppings_j">Jimmies</label><br/><input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/><label for="toppings_nuts">Nuts</label><br/><input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/><label for="toppings_cherry">Cherry</label></fieldset><p><input type="submit"/></p></form>#icecream_options { display:none; background-color: #eee; margin-left: 2em; }function displayIceCreamOptions() { var divico = document.getElementById('icecream_options'); var inputYes = document.getElementById('ic_yes'); if (inputYes.checked == true) { divico.style.display = 'block'; } else { divico.style.display = 'none'; } }

- Markup
- Style
- Script
- Screenshot

    <form method="get" name="ice_cream" id="ice_cream" action="http://cscie12.dce.harvard.edu/echo">
    <div>Would you like ice cream?<br/>
    <input type="radio" name="want" id="ic_yes" value="yes" onclick="displayIceCreamOptions()"/><label for="ic_yes">Yes</label><br/>
    <input type="radio" name="want" id="ic_no" value="no" onclick="displayIceCreamOptions()"/><label for="ic_no">No</label></div><fieldset id="icecream_options" style="display: none;"><legend>Ice Cream Options</legend><p>How would you like it?</p>

    <input type="radio" id="container_cup" name="container" value="cup"/><label for="container_cup">Cup</label><br/>
    <input type="radio" id="container_cone" name="container" value="cone"/><label for="container_cone">Cone</label><br/><p>Pick your toppings:</p>

    <input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/><label for="toppings_wc">Whipped cream</label><br/>
    <input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/><label for="toppings_j">Jimmies</label><br/>
    <input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/><label for="toppings_nuts">Nuts</label><br/>
    <input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/><label for="toppings_cherry">Cherry</label></fieldset><p>
    <input type="submit"/></p>

    </form>

In `style` element (`<style type="text/css">`) within `head` element:

    #icecream_options {
        display:none;
        background-color: #eee;
        margin-left: 2em;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    function displayIceCreamOptions() {
        var divico = document.getElementById('icecream_options');
        var inputYes = document.getElementById('ic_yes');
        if (inputYes.checked == true) {
          divico.style.display = 'block';
        } else {
          divico.style.display = 'none';
        }
    }

## JS: Form Validation

Validate form input using the `onsubmit` event attribute.

Things to note:

- `onsubmit` attribute to set handler for "submit" event
- `false` stops the form submission
- `this` refers to the instance of the object (the form)
- Validate function accepts an argument, which is the form object
- On failure, focus is put on failed input and background color changed.

Example 8.8 - Simple Form Validation - Example 8.8 | <form onsubmit="return Validate(this)" method="get" action="http://cscie12.dce.harvard.edu/echo" enctype="application/x-www-form-urlencoded"><div><label for="YourName1">Enter your name</label>: <input type="text" id="YourName1" name="YourName"/><br/><input type="submit" value="Submit Information"/></div></form>function Validate(myForm) { console.log(myForm); if(myForm.YourName.value == null || myForm.YourName.value == "") { console.log("in failure branch"); alert("Please enter your name!"); myForm.YourName.focus(); myForm.YourName.style.backgroundColor = '#ff3'; return false; } else { console.log("in success branch"); return true; } }

- Markup
- Script
- Screenshot

    <form onsubmit="return Validate(this)" method="get" action="http://cscie12.dce.harvard.edu/echo">
    <div><label for="YourName1">Enter your name</label>:
    <input type="text" id="YourName1" name="YourName"/><br/>
    <input type="submit" value="Submit Information"/></div>
    </form>

In `script` element within `head` element (`<script type="text/javascript">`):

    function Validate(myForm) {
      console.log(myForm);
      if(myForm.YourName.value == null || myForm.YourName.value == "") {
        console.log("in failure branch");
        alert("Please enter your name!");
        myForm.YourName.focus();
        myForm.YourName.style.backgroundColor = '#ff3';
        return false;
      } else {
        console.log("in success branch");
        return true;
      }
    }

## Form Validation and Regular Expressions

Q. What if we want to test for a string pattern other than "null" or "empty"?...
A. Regular Expressions!

Simplified Regular Expression for an email address:

`/^[\w\._-]+@[\w\._-]+\.[a-zA-Z]{2,7}$/`

`^`
  beginning of the string
`[\w\._-]+`
  [square brackets] indicate a character class
  "\w" is a word character
  "+" means 1 or more times
`@`
  the "@" part of the email address
`\.[a-zA-Z]{2,7}`
  matches the TLD (dot something, where something is 2 to 7 letters
`$`
  end of string

Example 8.9 - Form Validation with Regular Expressions - Example 8.9 | JavaScript example9.js | <form onsubmit="return Validate(this)" method="get" action="http://cscie12.dce.harvard.edu/echo" enctype="application/x-www-form-urlencoded"><div><label for="email1">Email Address</label>: <input type="text" size="32" name="email" id="email1"/><br/><input type="submit"/></div></form>

- Markup
- Script
- Screenshot

    <form onsubmit="return Validate(this)" method="get" action="http://cscie12.dce.harvard.edu/echo">
    <div><label for="email1">Email Address</label>:
    <input type="text" size="32" name="email" id="email1"/><br/>
    <input type="submit"/></div>
    </form>

In `head` element:

    <script type="text/javascript" src="example9.js"> </script>

Contents of example9.js

    /* validates that the entry is formatted as an email address */
    function Validate(thisForm) {
        var tocheck = thisForm.email.value;
        var re = /^[\w\._-]+@[\w\._-]+\.[a-zA-Z]{2,7}$/;
        if (!tocheck.match(re)) {
            alert("Please verify the email address format.");
            thisForm.email.focus();
            thisForm.email.style.backgroundColor = '#ff9';
            return false;
        } else {
            return true;
        }
    }

## Document Object Model (DOM)

    <html>
      <head>
        <title>My Schools</title>
      </head>
      <body>
        <h1>My Schools</h1>
        <ul>
          <li>
            <a href="http://www.harvard.edu/">Harvard University</a><br/>
            <img src="images/veritas.gif" alt="Harvard Shield" height="84" width="72"/>
          </li>
          <li>
            <a href="http://www.ku.edu/">University of Kansas</a><br/>
            <img src="images/KUSeal.gif" alt="University of Kansas Seal" height="73" width="72"/>
          </li>
        </ul>
      </body>
    </html>

## Javascript and DOM: Building Content

And do the same for the other three seasons to get:

## Javascript and DOM: Building Content

Example 8.10 - Example 8.10 | <div id="seasonslist1"><p><button onclick="makeSeasonsList(); return false;" type="submit">Click to append list of seasons</button></p></div>function makeSeasonsList() { var ul_node = document.createElement("ul"); // Autumn var li_node1 = document.createElement("li"); var li_text1 = document.createTextNode("Autumn"); li_node1.appendChild(li_text1); // Winter var li_node2 = document.createElement("li"); var li_text2 = document.createTextNode("Winter"); li_node2.appendChild(li_text2); // Spring var li_node3 = document.createElement("li"); var li_text3 = document.createTextNode("Spring"); li_node3.appendChild(li_text3); // Summer var li_node4 = document.createElement("li"); var li_text4 = document.createTextNode("Summer"); li_node4.appendChild(li_text4); // Append the list items to the ul ul_node.appendChild(li_node1); ul_node.appendChild(li_node2); ul_node.appendChild(li_node3); ul_node.appendChild(li_node4); // Place on page var container = document.getElementById("seasonslist1"); container.appendChild(ul_node); }

- Markup
- Script

     <div id="seasonslist1"><p><button onclick="makeSeasonsList(); return false;" type="submit">Click to append list of seasons</button></p>
    </div>

In `script` element within `head` element (`<script type="text/javascript">`):

    function makeSeasonsList() {
        var ul_node = document.createElement("ul");

        // Autumn
        var li_node1 = document.createElement("li");
        var li_text1 = document.createTextNode("Autumn");
        li_node1.appendChild(li_text1);

        // Winter
        var li_node2 = document.createElement("li");
        var li_text2 = document.createTextNode("Winter");
        li_node2.appendChild(li_text2);

        // Spring
        var li_node3 = document.createElement("li");
        var li_text3 = document.createTextNode("Spring");
        li_node3.appendChild(li_text3);

        // Summer
        var li_node4 = document.createElement("li");
        var li_text4 = document.createTextNode("Summer");
        li_node4.appendChild(li_text4);

        // Append the list items to the ul
        ul_node.appendChild(li_node1);
        ul_node.appendChild(li_node2);
        ul_node.appendChild(li_node3);
        ul_node.appendChild(li_node4);

        // Place on page
        var container = document.getElementById("seasonslist1");
        container.appendChild(ul_node);
    }

## Javascript and DOM: Building Content

Using an array (a list).

`var seasons = ['Spring','Summer','Autumn','Winter'];`

Iterate through Array

Example 8.11 - Example 8.11 | <div id="seasonslist2"><p><button onclick="makeSeasonsList();" type="submit">Click to append list of seasons</button></p></div>function makeSeasonsList() { ul_node = document.createElement("ul"); var seasons = ['Spring','Summer','Autumn','Winter']; for (i in seasons) { var mytext = i + " " + seasons[i]; var text_node = document.createTextNode(mytext); var li_node = document.createElement("li"); li_node.appendChild(text_node); ul_node.appendChild(li_node); }; var container = document.getElementById("seasonslist2"); container.appendChild(ul_node); }

- Markup
- Script

     <div id="seasonslist2"><p><button onclick="makeSeasonsList();" type="submit">Click to append list of seasons</button></p>
    </div>

In `script` element within `head` element (`<script type="text/javascript">`):

    function makeSeasonsList() {
        ul_node = document.createElement("ul");
        var seasons = ['Spring','Summer','Autumn','Winter'];
        for (i in seasons) {
          var mytext = i + " " + seasons[i];
          var text_node = document.createTextNode(mytext);
          var li_node = document.createElement("li");
          li_node.appendChild(text_node);
          ul_node.appendChild(li_node);
        };
        var container = document.getElementById("seasonslist2");
        container.appendChild(ul_node);
    }

Using forEach array method

Example 8.12 - Example 8.12 | <div id="seasonslist3"><p><button onclick="makeSeasonsList();" type="submit">Click to append list of seasons</button></p></div>function makeSeasonsList() { ul_node = document.createElement("ul"); var seasons = ['Spring','Summer','Autumn','Winter']; seasons.forEach(function(s){ var text_node = document.createTextNode(s); var li_node = document.createElement("li"); li_node.appendChild(text_node); ul_node.appendChild(li_node); }); var container = document.getElementById("seasonslist3"); container.appendChild(ul_node); }

- Markup
- Script

     <div id="seasonslist3"><p><button onclick="makeSeasonsList();" type="submit">Click to append list of seasons</button></p>
    </div>

In `script` element within `head` element (`<script type="text/javascript">`):

    function makeSeasonsList() {
        ul_node = document.createElement("ul");
        var seasons = ['Spring','Summer','Autumn','Winter'];
        seasons.forEach(function(s){
          var text_node = document.createTextNode(s);
          var li_node = document.createElement("li");
          li_node.appendChild(text_node);
          ul_node.appendChild(li_node);
        });
        var container = document.getElementById("seasonslist3");
        container.appendChild(ul_node);
    }

## Using a name/value object

`{"seasons" : ['Spring','Summer','Fall','Winter']}`

Example 8.13 - Example 8.13 | <div id="seasonslist2"><p><button onclick="makeSeasonsList(); return false;" type="submit">Click to append list of seasons</button></p></div>function makeSeasonsList() { ul_node = document.createElement("ul"); var mydata= {"seasons":['Spring','Summer','Fall','Winter']} ; var seasons = mydata.seasons; for (i in mydata.seasons) { var mytext = i + " " + seasons[i]; var text_node = document.createTextNode(mytext); var li_node = document.createElement("li"); li_node.appendChild(text_node); ul_node.appendChild(li_node); }; var container = document.getElementById("seasonslist2"); container.appendChild(ul_node); }

- Markup
- Script

     <div id="seasonslist2"><p><button onclick="makeSeasonsList(); return false;" type="submit">Click to append list of seasons</button></p>
    </div>

In `script` element within `head` element (`<script type="text/javascript">`):

    function makeSeasonsList() {
      ul_node = document.createElement("ul");
      var mydata= {"seasons":['Spring','Summer','Fall','Winter']}
    ;
      var seasons = mydata.seasons;
        for (i in mydata.seasons) {
          var mytext = i + " " + seasons[i];
          var text_node = document.createTextNode(mytext);
          var li_node = document.createElement("li");
          li_node.appendChild(text_node);
          ul_node.appendChild(li_node);
        };
        var container = document.getElementById("seasonslist2");
        container.appendChild(ul_node);
    }

## Table striping with Javascript

- United States Senate Table - Plain
- United States Senate Table - Striped with JS

- Use `onload` event attribute of `body` element to call striping function.
- Will use Document Object Model to access parts of the page
- Basic flow:
  - Get the table to stripe (`getElementById`)
  - Get the table body (`getElementsByTagName`)
  - Get the rows within the table body (`getElementsByTagName`)
  - Go through each row, and assign an "evenRow" or "oddRow" class attribute
    (`for` loop and `setAttribute` DOM method)

    function stripeTable(tableid) {
      var mytable = document.getElementById(tableid);
      // get tbody (i.e. we do not want to stripe the thead)
      var mytbody = mytable.getElementsByTagName('tbody');
      /*   getElementsByTagName gives us a Node List, so we need
         to access it as a list (Array), arrayname[i].
         Find all the tr within the tbody
      */
      var myrows =  mytbody[0].getElementsByTagName('tr');
      /*  Iterate over the node list of "tr" returned, setting
          the class appropriately
        */
      for(var i=0; i<myrows.length; i++) {
        if ((i + 1) % 2 == 0) {
          // even row -- the "%" operator is the "modulus" or remainder
          myrows[i].setAttribute('class','evenRow');
        } else {
          // odd row
          myrows[i].setAttribute('class','oddRow');
        }
      }
    }

## Things will go wrong...the Javascript Console is your friend

- United States Senate Table - Plain
- United States Senate Table - Striped with JS
- United States Senate Table - Striped with JS and Console Messages

    function stripeTable(tableid) {
      var mytable = document.getElementById(tableid);
      console.log("mytable is:");
      console.log(mytable);
      // get tbody (i.e. we dont' want to stripe the thead)
      var mytbody = mytable.getElementsByTagName('tbody');
      console.log("mytbody is:");
      console.log(mytbody);
      /*   getElementsByTagName gives us a Node List, so we need
         to access it as a list (Array), arrayname[i].
         Find all the tr within the tbody
      */
      var myrows =  mytbody[0].getElementsByTagName('tr');
      console.log("myrows is:");
      console.log(myrows);
      console.log("myrows length is: " + myrows.length);

      /*  Iterate over the node list of "tr" returned, setting
          the class appropriately
        */
      for(var i=0; i<myrows.length; i++) {
          var senatorname = myrows[i].getElementsByTagName('td')[0].firstChild.nodeValue;
          console.log(senatorname);
        if ((i + 1) % 2 == 0) {
          // even rows
          console.log("row with index of " + i + " is evenRow");
          myrows[i].setAttribute('class','evenRow');
        } else {
          // odd rows
          console.log("row with index of " + i + " is oddRow");
          myrows[i].setAttribute('class','oddRow');
        }
      }
    }

`console.log()` allows you output messages to a console.

## Your Work Easier with JavaScript Libraries

- jQuery
- Prototype
- Mootools

## jQuery

What is jQuery?
jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

Easier:

- document traversal
- document manipulation
- event handling
- animation
- Ajax
- cross-browser

## jQuery: Table Striping

Let's get started with jQuery by "striping" a table. The plain table comes from a list of United States Senators.

- Plain table: senate-plain.html
- Striped table: senate-striped.html
  Include some Javascript libraries (`jquery.js`) and write a function that selects the table rows and applies a class. Note that the jQuery selectors are like CSS selectors (and here we see custom jQuery selectors of `:even` and `:odd`).

    <script type="text/javascript" src="../js/jquery.js"> </script>
    <script type="text/javascript">
    $(document).ready(function()
        {
            $("#senatetable tbody tr:even").addClass('evenRow');
            $("#senatetable tbody tr:odd").addClass('oddRow');
        }
    );
    </script>

Plain table:

Striped table:

## jQuery and $(document).ready();

See: $(document).ready() for more explanation, including the shorthand of `$()`.

## jQuery Plugin - Tablesorter

Query Tablesorter Plugin makes dealing with tables even easier!

    $(document).ready(function() {
       $("table.tablesorter").tablesorter({
        "theme": "blue",
        "widgets": [
            "zebra"
        ]
    });
    });

- Plain table: senate-plain.html
- Sortable table: senate-tablesorter.html
  - Javascript
    - jQuery (jquery.js)
    - jQuery Tablesorter Plugin (jquery.tablesorter.js)
  - CSS
    - Use the "blue" theme from the tablesorter plugin
  - Assign tables with classes
  - jQuery "ready" function

Data passed to the "tablesorter" plugin:

    {
        "theme": "blue",
        "widgets": [
            "zebra"
        ]
    }

Sortable table:

Tables are constructed with `thead` and `tbody`. Simply by giving them a `class="sortable"`, the jQuery Tablesorter Plugin makes them 'sortable' and 'striped':

Senate data used with permission from GovTrack.US.
Table sorting is achieved through jQuery and the jQuery Tablesorter Plugin

## Tablesorter Example as a JSFiddle

Tablesorter Example as a JSFiddle

## Separation from Markup

In an earlier example, we used the "onclick" attribute to specify a javascript function to call:
hide-show.html | Hide/Show as JSFiddle

## Separation from Markup

- Use Javascript to add the "onclick" listener

Let's see how we can do this with jQuery. Items to note:

- Separation. The "click" handler is bound via JavaScript and not the onclick attribute.
- Fancier. jQuery provides many "effects" and "animations" (basic ones here are `fadeOut` and `fadeIn`)
- Default Behavior Stopped. The default behavior for event propagation can be stopped.
- Unobtrusive. JS is used to hide additional form elements.

Example 8.14 - JS Separation from Markup - Example 8.14 | <div id="cscie12-course2" style="font-family: calibri,verdana,tahoma,helvetica,sans-serif; float: left; width: 50%; padding: 10px; margin: 10px; border: medium solid black; background-color: #ffb;"><h3>CSCI E-12: Fundamentals of Website Development</h3><p> Harvard Extension School<br/> David Heitmeyer <br/> CSCI E-12 </p><p id="cscie12-description2"> This course provides a comprehensive overview of website development. Students explore the prevailing vocabulary, tools, and standards used in the field and learn how the various facets including HTML5, XHTML, CSS, JavaScript, Ajax, multimedia, scripting languages, HTTP, clients, servers, and databases function together in today's web environment. The course provides a solid web development foundation, focusing on content and client-side (browser) components (HTML5, XHTML, CSS, JavaScript, multimedia), with an overview of the server-side technologies. In addition, software and services that are easily incorporated into a website (for example, maps, checkout, blogs, content management) are surveyed and discussed. Students produce an interactive website on the topic of their choice for the final project and leave the course prepared for more advanced and focused web development studies. </p></div><div style="width: 20%; float: left; margin-left: 2em;"><p><strong>Hide/Show/Toggle Description</strong></p><ul><li><a href="#" id="hide">Hide</a></li><li><a href="#" id="show">Show</a></li><li><a href="#" id="toggle">Toggle</a></li></ul></div>$(document).ready(function() { $('#hide').click( function(event){ $('#cscie12-description2').fadeOut('slow'); event.preventDefault(); } ); $('#show').click( function(event){ $('#cscie12-description2').fadeIn('slow'); event.preventDefault(); } ); $('#toggle').click( function(event) { console.log('toggle!'); $('#cscie12-description2').toggle('slow'); event.preventDefault(); } ); });

- Markup
- Script
- Screenshot

    <div id="cscie12-course2" style="font-family: calibri,verdana,tahoma,helvetica,sans-serif; float: left; width: 50%; padding: 10px; margin: 10px; border: medium solid black; background-color: #ffb;"><h3>CSCI E-12: Fundamentals of Website Development</h3><p>Harvard Extension School<br/>David Heitmeyer<br/>CSCI E-12</p>
    <p id="cscie12-description2">This course provides a comprehensive overview of website development. Students explore the prevailing vocabulary, tools, and standards used in the field and learn how the various facets including HTML5, XHTML, CSS, JavaScript, Ajax, multimedia, scripting languages, HTTP, clients, servers, and databases function together in today's web environment. The course provides a solid web development foundation, focusing on content and client-side (browser) components (HTML5, XHTML, CSS, JavaScript, multimedia), with an overview of the server-side technologies. In addition, software and services that are easily incorporated into a website (for example, maps, checkout, blogs, content management) are surveyed and discussed. Students produce an interactive website on the topic of their choice for the final project and leave the course prepared for more advanced and focused web development studies.</p>
    </div><div style="width: 20%; float: left; margin-left: 2em;"><p><strong>Hide/Show/Toggle Description</strong></p>
    <ul>
    <li><a href="#" id="hide">Hide</a></li>
    <li><a href="#" id="show">Show</a></li>
    <li><a href="#" id="toggle">Toggle</a></li>
    </ul></div>

In `script` element within `head` element (`<script type="text/javascript">`):

    $(document).ready(function() {
      $('#hide').click(
        function(event){
          $('#cscie12-description2').fadeOut('slow');
          event.preventDefault();
        }
      );
      $('#show').click(
        function(event){
          $('#cscie12-description2').fadeIn('slow');
          event.preventDefault();
        }
      );
      $('#toggle').click(
        function(event) {
          console.log('toggle!');
          $('#cscie12-description2').toggle('slow');
          event.preventDefault();
        }
       );
    });

## Minified JS

Comments and unnecessary whitespace are removed.

- jquery-1.12.1: 287 kb
- jquery-1.12.1.min.js: 95 kb
  67% reduction!

### Minify Your JS (and CSS)

Some tools you can use to minify your JS:

- YUI Compressor. (JS and CSS)
- Minify JS
- and others (UglifyJS, JSMin, Closure Compiler)

## Load Your Core JS Library through a CDN

MaxCDN (jQuery CDN), Google, Microsoft, and cdnjs.com host several JS libraries through their CDNs.
Using jQuery with a CDN

### Why Use a CDN?

See: 3 reasons why you should let Google host jQuery for you (or any other CDN)

- Decreased latency
- Increased Parallelism
- Better Caching

Copyright © David Heitmeyer