Putting our newfound jQuery knowledge to some good use

Ok, so we've learned a few important jQuery fundementals, and some interesting tricks. Now it is time to apply this knowledge to an ectual project: a demo, responsive, HTML5 website. Let's put a working slideshow into this site using a custom jQuery plugin we're going to write....on our own! 

[click here to take a look at the Farm at Richville site with working slideshow]

[click here to download the exercise files]

[click here to download the tutorial PDF


jQuery Animations

We already used prebuilt jQuery animation methods in the last exercise whehter we were aware of it or not. The  .fadeIn() and .fadeOut() methods we used for our slideshow are simple jQuery functions that increase or reduce respectively the CSS opacity property of an element. As we can see, these prebuilt methods are very useful.  But jQuery provides a very useful method for the custom animation of certain CSS properties. A proper implementation of the .animate() method will have the following structure:

$("#some_element").animate( {some_property: value; some_other_property: value;}[, duration] [, easing] [, call back function] );

You can pass any CSS properties with numeric values and animate() will all chnage them together from the selected element's original properties to the new values you choose.  [Click here] to download the following simple examples:

Example 01: Simple animation

This demo simply calls two .animate() methods: 

  1.  $("#clickhere").click(function() {
  2.    $("#animate1").animate({
  3.     height: "20px",
  4.     width: "10px",
  5.    }, 1000);
  6.    $("#animate2").animate({
  7.     height: "50px",
  8.     width: "500px"
  9.    }, 1000);
  10.  });

Example 02: Animating Multiple CSS Properties

[See the demo]. Any CSS property with a numeric value can be animated with jQuery. Font-size, border-width, margin, padding, top, left, bottom, and right can be animated simply by passing the desired end point to jQuery.animate(). These properties can be expressed either as %, px, or in ems:

  1.     $("#clickhere").click(function() {
  2.         $("#animate1").animate({
  3.             height: "20px",
  4.             width: "50%",
  5.             padding: "5em",
  6.             marginLeft: "40px",
  7.             borderWidth: "5px"
  8.         }, 1000);
  9.     });

 


Example 03: Animation Callback Functions

[See the demo]. The .animate() method can also accept a callback function, to be called when the animation has finished:

  1.     $("#clickhere").click(function() {
  2.         $("#animate1").animate({
  3.             height: "12px",
  4.             width: "50px"
  5.         }, 1000, function() {
  6.             alert('done!');
  7.         });
  8.     });

 


Example 04: Animation Chaining

[See the demo]. Like any other jQuery method, .animate() can be chained to other animations. Unless otherwise specified, each subsequent call to .animate() will fire only after the previous call in completed.  

  1.    $("#clickhere").click(function() {
  2.     $("#animate1").animate({
  3.      width: "200px"
  4.     }, 600).animate({
  5.      height: "200px"
  6.     }, 600).animate({
  7.      width: "120px",
  8.      height: "120px"
  9.     }, 600).animate({
  10.      marginLeft: "100px",
  11.      borderWidth: "5px"
  12.     }, 600);
  13.    });

Example 05: Easing

[See the demo]. Assuming you include the jQueryUI library into your script, you make use of awesome animation easing properties.

  1.    $("#clickhere").click(function() {
  2.     $("#animate1").animate({
  3.      width: "200px"
  4.     }, 1000, "easeOutSine");
  5.     $("#animate2").animate({
  6.      width: "200px"
  7.     }, 2000, "easeOutExpo");
  8.     $("#animate3").animate({
  9.      width: "200px"
  10.     }, 3000, "easeOutBounce");
  11.    });

Putting Animation to Good Use

I have updated the Farm at Richville site to include a simple popup window when someone clicks on any of the in-content buttons. This is preferable to having them click to another page as it keeps them in the same space.

[Take a look at the demo] [Download the Exercise Files]


Homework: try the .animate() for yourself

Now that you have seen the .animate() function in action, try adding a more involved animation (or series of animations) for the yellow menu button in the Farm at Richville exercise files above. Additionally, you'll notice that, to close the jQuery popup, a user must click outside the rounded rectangle area. It may confuse people if there are no indications that this is how you close the popup. Therefore, attach a close button to the popup div that animates the popup out to the main website.

Here are the things you need to do:

  1. Add an interesting animation to the third (yellow) content button in the exercise files above.
  2. Add a close button to the popup div so that a user knows how to close it down. 
  3. Attach a close animation to the close button.

Continuing the jQuery UI: .sortable()

 The .sortable() plugin is another example of what makes jQuery so useful: it takes a job that would normally be a nightmare in normal JavaScript and simplifies it, in this case to just a single line. Not even a line, really - just 11 characters. Let's try an example:

Example 01: A Movable Feast

[Click here for the demo]  [Click here for exercise files]

As you can see from the above demo, it behaves very similar to what we did last week with the draggable and droppable plugins. After all, it's letting us drag and drop elements in the browser window. But this example does us one better: it keeps the elements sorted. Let's look at the code. A word of caution, though: it's rediculously easy.

The HTML is very straightforward. Here I have created a list of Ernest Hemingway novels that the user can reorder based on preference. Full disclosure: I haven't read any of these. I started A Movable Feast like 7 years ago, but I'll be honest: it was kind of boring. As far as the HTML is concerned, however, it's very sparse...like Hemingway's prose:

 HTML

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6.  <meta charset="utf-8">
  7.  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8.  <meta name="description" content="">
  9.  <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10.  <link rel="stylesheet" href="css/style.css">
  11. <script src="/js/libs/modernizr-2.5.3.min.js"></script>
  12. </head>
  13.   <body>
  14.   <h3>A Movable Feast: List Your Favorite Hemingway Novels!</h3>
  15.   <ul>
  16.    <li>Old Man and the Sea</li>
  17.  <li>The Sun Also Rises</li>
  18.     <li>For Whom the Bell Tolls</li>
  19.     <li>A Movable Feast</li>
  20.     <li>A Farewell to Arms</li>
  21.   </ul>    
  22. <script GARBAGE></script>
  23. <script GARBAGE></script>
  24. <script src="/js/plugins.js"></script>
  25. <script src="/js/script.js"></script>
  26. </body>
  27. </html>

Note that we are including both the jQuery core AND the jQuery UI library above, just after the body content. The CSS is also pretty simple, just some styling to make it look presentable

CSS

  1. @charset "UTF-8";
  2. /* CSS Document */
  3.  
  4. body{
  5.  font: "Lucida Sans Unicode", "Lucida Grande", Arial, sans-serif;
  6.  background: #FFF;
  7.  color: rgb(50, 50, 50);
  8.  margin: 0;
  9.  padding: 0;
  10. }
  11.  
  12. h4 {
  13.  margin: 5px;
  14. }
  15.  
  16. ul {
  17.  list-style: none;
  18.  width: 250px;
  19.  margin: 5px;
  20.  padding: 0px;
  21. }
  22.  
  23. li {
  24.  background: grey;
  25.  color: white;
  26.  padding: 3px;
  27.  width: 250px;
  28.  border: 1px solid #CCC;
  29. }

And finally, the jQuery, which we will place in the js/script.js fle:

jQuery

  1. $(document).ready(
  2.  function() {
  3.   $('ul').sortable();    
  4.  }
  5. );

 

Pretty simple, I know. All we're doing here upon $(document).ready() is calling an anonymous function that selects all <ul> tags and attaches the .sortable() plugin to each of them. This plugin essentially makes all children <li> tags draggable, but it also makes siblings reorder when a fellow list item is droped above or below them.


Example 02:

In this example we'll make our sortable list a little bit more interactive. To make it behave a little bit more like an actual application, we'll use essentially the same logic we used in the previous draggable/droppable examples.

[Click here for the demo] [Click here for the exercise files]

We have the HTML below:

HTML

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6.  <meta charset="utf-8">
  7.  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8.  <meta name="description" content="">
  9.  <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10.  <link rel="stylesheet" href="css/style.css">
  11.   <!--[if lt IE 7]>
  12.    <link type='text/css' href='css/IE_style.css' rel='stylesheet' />
  13.  <![endif]-->
  14. <script src="/js/libs/modernizr-2.5.3.min.js"></script>
  15. </head>
  16.   <body>
  17.       <ul id='finderCategoryFiles'>
  18.       <li class="finderCategoryFile">
  19.         <div class="finderCategoryFileIcon"></div>
  20.         <h5 class="finderCategoryFileTitle">
  21.           The Sun Also Rises
  22.         </h5>
  23.         <div class="finderCategoryFilePath">
  24.             Read About It!
  25.           </a>
  26.         </div>
  27.       </li>
  28.       <li class="finderCategoryFile">
  29.         <div class="finderCategoryFileIcon"></div>
  30.         <h5 class="finderCategoryFileTitle">
  31.           A Farewell to Arms
  32.         </h5>
  33.         <div class="finderCategoryFilePath">
  34.             Read About It!
  35.           </a>
  36.         </div>
  37.       </li>
  38.       <li class="finderCategoryFile">
  39.         <div class="finderCategoryFileIcon"></div>
  40.         <h5 class="finderCategoryFileTitle">
  41.          For Whom the Bell Tolls
  42.         </h5>
  43.         <div class="finderCategoryFilePath">
  44.             Read About It!
  45.           </a>
  46.         </div>
  47.       </li>
  48.       <li class="finderCategoryFile">
  49.         <div class="finderCategoryFileIcon"></div>
  50.         <h5 class="finderCategoryFileTitle">
  51.           The Old Man and the Sea
  52.         </h5>
  53.         <div class="finderCategoryFilePath">
  54.             Read About It!
  55.           </a>
  56.         </div>
  57.       </li>
  58.       <li class="finderCategoryFile">
  59.         <div class="finderCategoryFileIcon"></div>
  60.         <h5 class="finderCategoryFileTitle">
  61.           A Moveable Feast
  62.         </h5>
  63.         <div class="finderCategoryFilePath">
  64.             Read About It!
  65.           </a>
  66.         </div>
  67.       </li>
  68.     </ul>
  69.  
  70. <script GARBAGE></script> 
  71. <script GARBAGE></script>
  72. <script src="/js/plugins.js"></script>
  73. <script src="/js/script.js"></script>
  74. </body>
  75. </html>

You can see that each item in our list has a main finderCategoryFile class, an empty finderCategoryFileIcon div that will hold an icon image, a title, and a link to more info on Wikipedia. This is similar to how we created Finder folder icons in the previous draggable/droppable examples. The CSS is also similar to the previous Finder-emulating examples:

CSS

  1. @charset "UTF-8";
  2. /* CSS Document */
  3.  
  4. html,
  5. body {
  6.     width: 100%;
  7.     height: 100%;    
  8. }
  9. body {
  10.     font: 12px "Lucida Grande", Arial, sans-serif;
  11.     background: rgb(189, 189, 189)
  12.       url('../img/Bottom.png') repeat-x bottom;
  13.     color: rgb(50, 50, 50);
  14.     margin: 0;
  15.     padding: 0;
  16. }
  17. ul#finderCategoryFiles {
  18.     position: absolute;
  19.     top: 0;
  20.     bottom: 0px;
  21.     left: 0;
  22.     width: 300px;
  23.     border-bottom: 1px solid rgb(64, 64, 64);
  24.     border-right: 1px solid rgb(64, 64, 64);
  25.     background: #fff;
  26.     list-style: none;
  27.     margin: 0;
  28.     padding: 0;
  29. }
  30. li.finderCategoryFile {
  31.     clear: both;
  32.     padding: 5px 5px 10px 5px;
  33.     min-height: 102px;
  34.     width: 290px;
  35. }
  36. li.finderCategoryFile h5 {
  37.     font: normal 12px "Lucida Grande", Arial, sans-serif;
  38.     margin: 0;
  39. }
  40. div.finderCategoryFileIcon {
  41.     float: left;
  42.     width: 80px;
  43.     height: 102px;
  44.     background:url(../img/hemingway_book.png) no-repeat;
  45. }
  46. h5.finderCategoryFileTitle,
  47. div.finderCategoryFilePath {
  48.     padding-left: 55px;
  49. }
  50. li.finderCategoryFileSelected {
  51.     background: rgb(51, 153, 204);
  52.     color: white;
  53. }
  54. li.finderCategoryFileSelected a {
  55.     color: lightblue;
  56. }

The jQuery follows almost identical logic to the previous Finder example:

jQuery

  1. $(document).ready(
  2.   function() {
  3.     $('li.finderCategoryFile').mousedown(
  4.       function() {
  5.         $('li.finderCategoryFile').not(this)
  6.           .removeClass('finderCategoryFileSelected');
  7.  
  8.         $(this).addClass('finderCategoryFileSelected');
  9.       }
  10.     );
  11.  
  12.     $('ul#finderCategoryFiles').sortable();
  13.   }
  14. );

First we pass an anonymous function that is called when the document is fully loaded into the DOM. Chained to this function is a .mousedown() method, which 1.) takes care of removing the selected class .finderCategoryFileSelected from any previously selected element. It then adds this class to whatever element was clicked on. With this logic taken care of, we then make sortable the unnumbered list with the id  #finderCategoryFiles.


Example 03: Customizing the .sortable() event

Just as we did with .draggable() and .droppable(), .sortable() can be passed an object literal as a parameter. This object serves as nothing more than a wrapper for plugin-specific option keywords and generic, custom functions.

One of the options we'll pass .sortable() is placeholder. In this case, 'placeholder' refers to the space, appearing when an element from a sortable group is dragged, to indicate where the dragged element was grabbed from, or where it will drop into if let go. By default (as in the previous example), this space is white. Kinda boring, so we'll pass placehoder a custom CSS class to make it look a little more interesting.

The second option we'll pass .sortable() is helper. We saw this same option with the .draggable() plugin and that's because helper in jQuery refers to helping the user with feedback. The helper option specifies the element that is displayed during a drag and drop scenario. By default, it's the original element the user dragged on, as in the example above, but there may be instances where you want it to be a different element. helper takes two arguements or paramters: an event object (a referrence to the drag event), and a reference to the element being dragged for resorting.

Now that we know what they are, let's use them. We can use essentially the same code that we used above in Example 02, with a couple temporary classes added to the CSS:

Additional CSS (add to style.css from Example 02) 

  1. li.tmpPlaceholder {
  2.     background: rgb(51, 153, 204);
  3.     height: 102px;
  4. }
  5. li.tmpHelper {
  6.     border: 4px solid rgb(204, 183, 0);
  7. }

 And an object literal passed to our .sortable() call like so:

  1.     $('ul#finderCategoryFiles').sortable({
  2.       placeholder: 'tmpPlaceholder',
  3.       helper: function(e, element) {
  4.       return $(element).clone().addClass('tmpHelper');
  5.       }
  6.     });

 As you can see above, placeholder simply accepts any CSS class as its value. helper, however, has been assigned a function as its value. This function is very simple: all it does is return a clone of the object selected for resorting, with a tmpHelper class added to it. This is only necessary because helper doesn't accept CSS classes as values.


Example 04: Connecting Sortable Lists

Now it gets interesting. The .sortable() plugin also accepts an option that will allow it to interact with other lists. Let's try an example.

[Click here for the demo] [Click here for the exercise files]

The HTML is almost identical to the previously example, with one exception: an additional unnumbered list at the very end:

HTML

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6.  <meta charset="utf-8">
  7.  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8.  <meta name="description" content="">
  9.  <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10.  <link rel="stylesheet" href="css/style.css">
  11.   <!--[if lt IE 7]>
  12.    <link type='text/css' href='css/IE_style.css' rel='stylesheet' />
  13.  <![endif]-->
  14.  [removed][removed]
  15. </head>
  16.   <body>
  17.       <ul id='finderCategoryFiles'>
  18.       <li class="finderCategoryFile">
  19.         <div class="finderCategoryFileIcon"></div>
  20.         <h5 class="finderCategoryFileTitle">
  21.           The Sun Also Rises
  22.         </h5>
  23.         <div class="finderCategoryFilePath">
  24.             Read About It!
  25.           </a>
  26.         </div>
  27.       </li>
  28.       <li class="finderCategoryFile">
  29.         <div class="finderCategoryFileIcon"></div>
  30.         <h5 class="finderCategoryFileTitle">
  31.           A Farewell to Arms
  32.         </h5>
  33.         <div class="finderCategoryFilePath">
  34.             Read About It!
  35.           </a>
  36.         </div>
  37.       </li>
  38.       <li class="finderCategoryFile">
  39.         <div class="finderCategoryFileIcon"></div>
  40.         <h5 class="finderCategoryFileTitle">
  41.          For Whom the Bell Tolls
  42.         </h5>
  43.         <div class="finderCategoryFilePath">
  44.             Read About It!
  45.           </a>
  46.         </div>
  47.       </li>
  48.       <li class="finderCategoryFile">
  49.         <div class="finderCategoryFileIcon"></div>
  50.         <h5 class="finderCategoryFileTitle">
  51.           The Old Man and the Sea
  52.         </h5>
  53.         <div class="finderCategoryFilePath">
  54.             Read About It!
  55.           </a>
  56.         </div>
  57.       </li>
  58.       <li class="finderCategoryFile">
  59.         <div class="finderCategoryFileIcon"></div>
  60.         <h5 class="finderCategoryFileTitle">
  61.           A Moveable Feast
  62.         </h5>
  63.         <div class="finderCategoryFilePath">
  64.             Read About It!
  65.           </a>
  66.         </div>
  67.       </li>
  68.     </ul>
  69.    
  70.  <!-- Another list we will connect the previous list with in the jQuery -->
  71.     <ul id='finderOtherCategoryFiles'>
  72.     </ul>
  73.  
  74. <script GARBAGE></script>
  75. <script GARBAGE></script>
  76. <script src="/js/plugins.js"></script>
  77. <script src="/js/script.js"></script>
  78. </body>
  79. </html>

 The CSS is also very similar to the previous example:

CSS

  1. html,
  2. body {
  3.     width: 100%;
  4.     height: 100%;    
  5. }
  6. body {
  7.     font: normal 12px "Lucida Grande", Arial, sans-serif;
  8.     background: rgb(189, 189, 189)
  9.       url('../img/Bottom.png') repeat-x bottom;
  10.     color: rgb(50, 50, 50);
  11.     margin: 0;
  12.     padding: 0;
  13. }
  14. div#finderCategoryFileWrapper {
  15.     position: absolute;
  16.     top: 0;
  17.     right: 0;
  18.     bottom: 23px;
  19.     left: 0;
  20. }
  21. ul#finderCategoryFiles,
  22. ul#finderOtherCategoryFiles {
  23.     float: left;
  24.     height: 100%;
  25.     width: 210px;
  26.     border-bottom: 1px solid rgb(64, 64, 64);
  27.     border-right: 1px solid rgb(64, 64, 64);
  28.     background: #fff;
  29.     list-style: none;
  30.     margin: 0;
  31.     padding: 0;
  32. }
  33. li.finderCategoryFile {
  34.     clear: both;
  35.     padding: 5px 5px 10px 5px;
  36.     min-height: 102px;
  37.     width: 200px;
  38. }
  39. li.finderCategoryFile h5 {
  40.     font: normal 12px "Lucida Grande", Arial, sans-serif;
  41.     margin: 0;
  42. }
  43. div.finderCategoryFileIcon {
  44.     float: left;
  45.     width: 80px;
  46.     height: 102px;
  47.     background: url('../img/hemingway_book.png') no-repeat;
  48. }
  49. h5.finderCategoryFileTitle,
  50. div.finderCategoryFilePath {
  51.     padding-left: 55px;
  52. }
  53. li.finderCategoryFileSelected {
  54.     background: rgb(24, 67, 243);
  55.  color: white;
  56. }
  57. li.finderCategoryFileSelected a {
  58.     color: lightblue;
  59. }
  60. .finderCategoryFilePlaceholder {
  61.     background: rgb(230, 230, 230);
  62.     height: 120px;
  63. }

And Finally the jQuery, which adds a few options to the .sortable() call:

jQuery

  1. $(document).ready(
  2.   function() {
  3.     var $selectedFile;
  4.  
  5.     $('li.finderCategoryFile').mousedown(
  6.       function() {
  7.         if ($selectedFile && $selectedFile.length) {
  8.           $selectedFile.removeClass('finderCategoryFileSelected');
  9.         }
  10.  
  11.         $selectedFile = $(this);        
  12.         $selectedFile.addClass('finderCategoryFileSelected');
  13.       }
  14.     );
  15.  
  16.     $('ul#finderCategoryFiles').sortable({
  17.       connectWith : [
  18.         'ul#finderOtherCategoryFiles'
  19.       ],
  20.       placeholder: 'finderCategoryFilePlaceholder',
  21.       opacity: 0.8,
  22.       cursor: 'move'
  23.     });
  24.    
  25.     $('ul#finderOtherCategoryFiles').sortable({
  26.       connectWith : [
  27.         'ul#finderCategoryFiles'
  28.       ],
  29.       placeholder: 'finderCategoryFilePlaceholder',
  30.       opacity: 0.8,
  31.       cursor: 'move'
  32.     });
  33.   }
  34. );

The function call we're passing $(document).ready() does something slightly different in the first few lines to deselect any previously selected list item and then select the selected item. First, a global variable ($selectedFile) is declared. Then a .mousedown() event is added to our list item elements. The global variable $selectedFile is tested to see if it exists AND if has something in it (i.e. $selectedFile.length). If these conditions have been met, then we must have set $selectedFile with a reference to one of our list items earlier on in the runtime. Therefore we'll need to remove the selected CSS class from whichever element was previously selected. Though it requires a global variable, removing the selected class in this way is a bit more direct than removing it from all list items and then adding again. And by 'more direct',  I mean more efficient

Once the selected class is removed, we can reset the $selectedFile variable to the currently selected list item and add the selected class to it:

  1.         $selectedFile = $(this);        
  2.         $selectedFile.addClass('finderCategoryFileSelected');

Then we do something interesting for both <ul> elements: we make them sortable, and we pass in an object literal with specific options, the first option being connectWith. This option accepts a reference to another list-item and sets up a one-way connection with it. In other words, a user can now drag a list item from this list to the one specified. We want to make this a two-way connection, so we simply select the other list, make it sortable, and then pass it a connectWith value for the first list. Now the two lists in our HTML are essentially 'connected', and list items can be dragged and dropped between them.

Two of the other options you've seen - placeholder and opacity – and they both accept CSS classes. The fourth option – cursor – mirrors a CSS property of the same name. In both cases, cursor changes the mouse cursor to one of a set of OS supported cursor icons.


The Accordion UI in jQuery 

Broadly speaking, an accordion, in the context of the user interface, is a grouping of content items that open only one pane item at a time, hiding any previously open items or panes. They can be (and have been) built in various scripting languages, including Flash/ActionScript, JavaScript, Python, Java and C++. 

Accordions are relatively simple components for organizing content, but they can be kind of a hassle to code from scratch. They imply mouse click events, animations, and a lot of formatting options. Luckily the jQuery UI library includes a fully customizable accordion plugin, so we don't have to worry about the heavy lifting. Not surprisingly, it is called .accordion()

Let's take a look at an example. [Click here for the demo] [Click here for the exercise files]

The HTML: nothing special – just a simple list with information about the five foods groups. Remember to eat your vegetables!

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6.  <meta charset="utf-8">
  7.  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8.  <meta name="description" content="">
  9.  <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10.  <link rel="stylesheet" href="css/style.css">
  11. </head>
  12.   <body>
  13.     <h4>The Five Food Groups</h4>
  14.     <ul>
  15.       <li>
  16.         <a href='#'>Bread+Cereals</a>
  17.         <p>
  18.           Grains, also called cereals and sometimes inclusive of potatoes and other starches, is often the largest category in nutrition guides. Examples include wheat, rice, oats, barley, bread and pasta.
  19.         </p>
  20.       </li>
  21.       <li>
  22.         <a href='#'>Fruit+Vegetables</a>
  23.         <p>
  24.           Fruit, sometimes categorized with vegetables, is typically a medium-sized category in nutrition guides, though occasionally a small one. Examples include apples, oranges, bananas, berries and melons. Vegetables, sometimes categorized with fruit and occasionally inclusive of legumes, is typically a large category second only to grains, or sometimes equal to grains, in nutrition guides. Examples include spinach, carrots, onions, peppers, and broccoli.
  25.         </p>
  26.       </li>
  27.       <li>
  28.         <a href='#'>Dairy</a>
  29.         <p>
  30.           Dairy, also called milk products and sometimes categorized with milk alternatives or meat, is typically a smaller category in nutrition guides. Examples of dairy products include milk, yogurt and cheese. Though they are also dairy products, ice cream is typically categorized with sweets and butter is typically classified with fats and oils in nutrition guides.
  31.         </p>
  32.       </li>
  33.       <li>
  34.         <a href='#'>Meat</a>
  35.         <p>
  36.           Meat, sometimes labeled protein and occasionally inclusive of legumes, eggs, meat analogues and/or dairy, is typically a medium- to smaller-sized category in nutrition guides. Examples include chicken, fish, turkey, pork and beef.
  37.         </p>
  38.       </li>
  39.       <li>
  40.         <a href='#'>Fats, Oils+Sweets</a>
  41.         <p>
  42.           Fats and oils, sometimes categorized with sweets, is typically a very small category in nutrition guides, if present at all, and is sometimes listed apart from other food groups. Examples include cooking oil, butter, margarine and shortening. Sweets, also called sugary foods and sometimes categorized with fats and oils, is typically a very small category in nutrition guides, if present at all, and is sometimes listed apart from other food groups. Examples include candy, soft drinks, cake, pie and ice cream.
  43.         </p>
  44.       </li>
  45.     </ul>
  46. <script src="js/libs/jquery-1.7.2.min.js"></script> <script src="js/libs/jquery-ui-1.8.20.custom.min.js"></script> <script src="js/plugins.js"></script> <script src="js/script.js"></script>
    </body>
  47. </html>

The CSS: this is all presentational. However, as we shall see, it will not be sufficient in controlling how the accordion example looks on screen.

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body {
  4.     font: 12px "Lucida Grande", Arial, sans-serif;
  5.     background: #fff;
  6.     color: rgb(50, 50, 50);
  7.     margin: 0;
  8.     padding: 0;
  9. }
  10. h4 {
  11.     margin: 5px;    
  12. }
  13. ul {
  14.     list-style: none;
  15.     margin: 0;
  16.     padding: 15px 5px;
  17. }
  18. li {
  19.     background: gold;
  20.     padding: 3px;
  21.     width: 244px;
  22.     margin: 1px;
  23. }


Finally, the jQuery: shockingly easy. Take that, Flash!

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion();
  4.   }
  5. );

Let's take a look at it in a browser. As you can see, panes collapse and expand upon user interaction, but the heights of the elements are a little odd:

Screen Shot 2012-05-08 at 3.11.53 PMScreen Shot 2012-05-08 at 3.11.45 PM



 

.accordian() Options

Options: this is where the .accordion() plugin becomes really useful. Like many jQuery UI plugins and widgets, .accordion() accepts options wrapped in an object, passed in as an argument in the code.

autoHeight: one of these options is set to true by default, causing all list items to take the height of the highest list item. We'll set it to false by adding an options object, as in the jQuery below:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.       autoHeight: false  
  5.     });
  6.   }
  7. );

Insert the autoHeight: false option into your .accordion() call and viola! The list items each take on the height of their content…like they usually do.

 


 activeAnother useful option is active, which sets the actively open panel of the .accordion(). To use it, we need only specify the index of the item we want open. Remember that indexes are number 0-n, e.g:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.        autoHeight: false,
  5.        active: 2
  6.     });
  7.   }
  8. );

With updated code in place, refresh your browser and behold the goodness! Note that you can also pass the active option a CSS class name associated with one of the list items in your accordion list. It just takes longer and requires going permanently editing your HTML document if you haven't already done so.


alwaysOpen: Normally an instance of an .accordian() is always open to at least one pane. Setting the alwaysOpen option to false will allow it to be completely closed. This is useful if you want to have it tucked away. Pass this code into our growing collection of options to implement it:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.        autoHeight: false,
  5.        active: 2,
  6.        alwaysOpen: false
  7.     });
  8.   }
  9. );

eventThe event option determines which event triggers the accordion to open to a particular pane: a click on that pane's anchor, or a mouseover that pane's anchor. Let's set it to 'mouseover' make it a little more dynamic:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.        autoHeight: false,
  5.        active: 2,
  6.        alwaysOpen: false,
  7.        event: 'mouseover'
  8.     });
  9.   }
  10. );

header: The .accordion() plugin chooses the first link (or anchor) in each list item as the header for that accordion pane. The header is also the element that is clicked on or moused over to open a panel. Sometimes you may want something other than a hyperlink to do so. If you want to use a custom header element, like an <h3> tag, or even a <div> with a specific class associated with it, you can use the header option and pass it the selector for that element/class. E.g.: 

First we'll need to edit the HTML:

  1.       <li>
  2.         <h3>Bread+Cereals</h3>
  3.         <p>
  4.           Grains, also called cereals ... rice, oats, barley, bread and pasta.
  5.         </p>
  6.       </li>

And the new header option passed to our .accordion() instance:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.        autoHeight: false,
  5.        active: 2,
  6.        alwaysOpen: false,
  7.        event: 'mouseover',
  8.        header: 'h3'
  9.     });
  10.   }
  11. );

Make your .accordion() sortable: this isn't really an option, but more of really cool feature that the jQuery UI offers. Because jQuery makes it easy to chain together methods and plugins, we can easily make our accordion object a sortable object by chaining a .sortable() call to it. We'll pass this .sortable call some options as well:

  1. $(document).ready(
  2.   function() {
  3.     $('ul').accordion({
  4.        autoHeight: false,
  5.        active: 1,
  6.        alwaysOpen: false,
  7.        event: 'mouseover',
  8.     header: 'h3',
  9.     })
  10.     .sortable({
  11.       axis: "y",
  12.       handle: "h3"
  13.     });
  14.   }
  15. );

 

 

o;

JavaScript! Yay!!!

So, we've finally gotten to the portion of the class where we get to work with JavaScript. JavaScript is a browser or client-side, interpretive, scripting language that has been around since 1995, when it was called LiveScript and it was maintained by the browser company Netscape as a way of adding interactivity to web pages. We're going to be exploring JavaScript via jQuery, a very popular JavaScript framework that is currently blowing up huge. 

framework, in this sense, is a comprehensive library of shortcut methods (a.k.a. functions) and objects that are all built with JavaScript. In other words, developers took many of the functions and classes they had already been using in JavaScript, stuck them all in a single library file, and made them accessible with shortcut syntax that we call jQuery.  But first, a review of the Document Object Model: 

Document Object Model

DOM diagram

Above is a sketch of an example Document Object Model, or DOM. The DOM is a good way of looking at an HTML document as a hierarchical tree structures of different objects, as is the object model in general. What's an object? Well, anything really.

Parent/Child Relationship

A car is an object. But a car is also the top object of a giant hierarchy of smaller objects. A car seat, steering wheel, drive-train, and engine, are all objects. They are, in fact, child objects of the car, which is thus the parent object.

But an engine is also a parent object, because it has a crapload of child elements, such as the spark-plugs, the distributor, the crank case, engine block, crank shaft, flywheel, belts, pistons...and a whole lot of other stuff I don't really understand. 

engine components1
Look at all dem kids, yo!

But the point here is I don't need to know how an engine works. I never need to even look at the engine: that's what mechanics are for! Similarly, I don't always need to know how objects work in code. 

For example, we've been using links, lists, divs, typography, and many other types of objects this semester, without ever really knowing how or why the browser renders them the way it does. Likewise, we will be using objects in this next section that we may not fully understand each piece of. That's what hardcore developers are for!

Regardless, a basic understanding of the DOM can help, because it clues us into how code accesses specifics objects or groups of objects. Therefore, we shall likely refer back to it often. That said, let's start coding some jQuery!

JQuery 

Example #1

We'll start with a simple example. Create an HTML doc with the following code and call it index.html:

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8. <meta name="description" content="">
  9. <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10. <link rel="stylesheet" href="css/style.css"> <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body>
  13. <p>
  14. jQuery is not loaded.
  15. </p>
  16. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
  17. <script>window.jQuery || document.write('<script src="js/libs/jquery-3.1.1.min.js"><\/script>')</script> <script src="js/plugins.js"></script>
  18. <script src="js/script.js"></script>
  19. </body>
  20. </html>



Then create the following CSS file and name it style.css:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body { font: 16px sans-serif; }
  4.  
  5. p { color: red; border: 1px solid red; padding: 5px; margin: 5px; }
  6.  
  7. p.tmpFrameworkLoaded { color: green; border: 1px solid green; }


and place the following JavaScript in a js/script.js file:

  1. // JavaScript Document
  2. if ($) {
  3.  
  4. $(document).ready( function() {
  5.  
  6. $('p').addClass('tmpFrameworkLoaded');
  7.  
  8. $('p').text('jQuery successfully loaded and running!');
  9.  
  10. } );
  11.  
  12. }

Example #1 in action

In the previous code, we created a simple HTML5 document with nothing special in the body: 

<p>jQuery is not loaded.</p>

But if we then load this into a browser, we will see the following:  

jquery not loaded

This shouldn't be all that suprising, since that message appears in the HTML. But the jQuery code we place in script.js should have given us the following: 

jquery loaded

This example is a simple test to see if jQuery has loaded properly. Since we didn't download the jQuery library, it should be no surprise that it doesn't work. Downloading jQuery is easy: simply go to the  jQuery.com download section and download the most recent version (compressed or uncompressed – it doesn't matter, though compressed is smaller in size and, therefore, loads faster).  Whichever version you have, you'll see that it is contained inside a single JavaScript file. This file should be saved into a js/libs folder like so:

jquery install
Once you have installed (a.k.a. saved) jQuery, open up your index.html file in a browser again to test it.


Example #1 Explained

So here's what is going on the previous example. The HTML is pretty simple: just a simple <p> tag with a default message in it. In the CSS file we created, this simple style declaration:

p { color: red; border: 1px solid red; padding: 5px; margin: 5px; }

which applies to all <p> tags in the HTML document, including the aforementioned <p> tag, and the message text within it. In the script.js file we have the following code: 


$('p').addClass('tmpFrameworkLoaded');This code uses the jQuery object selector ($) and, in this case, it is selecting all HTML <p> elements in the DOM. It is then calling the jQuery addClass function on all <p> tags. This nifty function simply attaches CSS classes to whatever elements it is "chained" to.  The class that is attached is passed as a parameter to the addClass function, adding to (and, in this case, overiding) whatever styles the tag had prior. In this case the class is .tmpFrameworkLoaded , the definition of which is defined in our CSS file:

p.tmpFrameworkLoaded { color: green; border: 1px solid green; }

The next line of jQuery uses the jQuery text function to change the text within all <p> and </p> tags to whatever string of characters is passed as a parameter: 

$('p').text('jQuery successfully loaded and running!'); 

If jQuery has indeed been loaded successfully, the $s, the addClass and text functions, and all the other jQuery syntax in our script.js file should work and we will be presented with an HTML document, altered directly in the browser, to look like this:

jquery loaded


How Is This Better Than Good Ole' JavaScript? 

I'm so glad you asked! Well, this is a simple example – realy only a couple of choice lines – that changes a few things around in our DOM (Document Object Model).  As simple as it is, however, if we wanted to do the same thing using standard JavaScript, with no APIs or frameworks, it would look like this:

  1. // JavaScript Document
  2. window.onload = function() {
  3.  
  4. var $p = document.getElementsByTagName('p')[0];
  5.  
  6. $p.className = 'tmpFrameworkLoaded';
  7.  
  8. if($p.innerText) {
  9.  
  10. $p.innerText = 'jQuery successfully loaded and running!';
  11.  
  12. } else {
  13.  
  14. $p.textContent = 'jQuery successfully loaded and running!';
  15.  
  16. }
  17.  
  18. };

Yikes! Variable declarations?! getElementsBy TagName?! If/else statements?! That code is a hot mess! However, before jQuery was invented in 2006, this was the only way to do it. 


So What Makes jQuery Better? 

One thing that makes jQuery far easier to implement than standard Javascript is its selectors API. We're already quite familar with the concept of a selector: we've been using them constantly in our CSS files. In the following code snippet, bodya, and .highlight and all selectors:

body{ padding: 0px; margin: 0px; background: url("/images/bg.gif") #ccc no-repeat; }
a:link, a:hover{ color: red; }
.highlight{ color: black; background-color: yellow; }

As you can see, selectors are what CSS uses to reference HTML elements in general, and class names and ID tag specifically, with the intent of making them look and feel a certain way. In jQuery the concept is the same, but rather than determine styling,  jQuery determines behavior. Take the following HTML code...go on, literally take it, and save it as an HTML document.

Example #2: Controlling Links

  1. <!doctype html><!--[if lt IE 7]> <html lang="en"> <![endif]--><!--[if IE 7]> <html lang="en"> <![endif]--><!--[if IE 8]> <html lang="en"> <![endif]--><!--[if gt IE 8]><!-->
  2. <html class="no-js"lang="en"><!--<![endif]-->
  3. <head>
  4. <metacharset="utf-8">
  5. <metahttp-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <metaname="description" content="">
  7. <metaname="author" content="">
  8. <metaname="viewport" content="width=device-width">
  9. <link rel="stylesheet" href="css/style_02.css">
  10. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body>
  13. <ul id="tmpFavorites">
  14. <li><a href="http://www.google.com">Google</a></li>
  15. <li><a href="http://www.facebook.com">FaceBook</a></li>
  16. <li><a href="http://www.apple.com">Apple</a></li>
  17. <li><a href="http://instagr.am/">Instagram</a></li>
  18. </ul>
  19. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js" ></script>
  20. <script>window.jQuery ||document.write('<script src="js/libs/jquery-3.1.1.min.js"><\/script>')</script>
  21. <script src="js/plugins.js"></script>
  22. <script src="js/script_02.js"></script>
  23. </body>
  24. </html>

The HTML above contains a simple un-ordered list of common links. Nothing special... Let's try the code and see what it does. Then we're going to add a stylesheet containing the following code:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body { font: 16px sans-serif; }
  4.  
  5. ul {
  6. list-style: none;
  7. margin: 0;
  8. padding: 0;
  9. }
  10.  
  11. a{ text-decoration: none; }


and finally we're going to place the following jQuery code in our script_02.js file

  1. // JavaScript Document
  2. //create a new js object called tempExample
  3. var tmpExample = {
  4. //create a member method called ready
  5. ready : function(){
  6. // Find and return all links in ul#tmpFavorites, found in the jQuery object ($)...
  7. //attach a click event to each link
  8. $("ul#tmpFavorites li a").click(
  9. //pass the click event an anonymous function, with the event object ($e) as a parameter...
  10. function($e){
  11. //use the preventDefault() function to inhibit the default link click action
  12. $e.preventDefault();
  13. //and instead open a new browser window (or tab)
  14. window.open(this.href, "CoolLinks", ""); }
  15. //first parameter: the URL opened in the new window
  16. //second parameter: the name of the window or tab
  17. //third paramterL: a string containing window options, which we're leaving blank for now.
  18. );
  19. }
  20. };
  21. /*the above object and function doesn't get called until the entire document, and thus the DOM, has loaded. To make sure of this, we'll pass a reference to the tmpExample's ready function using the built-in jQuery $(document).ready*/
  22.  
  23. $(document).ready(tmpExample.ready);

Example #2: Explained

The jQuery code above is fully commented, but here is a rundown of what it's doing: 1.) The tmpExample object is created, along with a member method entitled ready. Then it just sits there in memory. 2.) As soon as the DOM is fully loaded, jQuery calls the $(document).ready() function we placed inside our script_02.js file. But notice we also passed it a reference to the tmpExample.ready object method, declared above. 3.) Because we did this, the browser will also execute this code.   

This example demonstrates the essence of the jQuery selector API: after the DOM is fully loaded into the browser's memory, this bit of code: 
<span style="line-height: 22.4px;">$(‘ul#tmpFavorites li a’).click()</span>

uses the main jQuery selector ($) and then more specifically selects all links with each list item of the unnumbered list with the #tmpFavorites ID. It looks a lot like CSS, and this is not a coincidence: the jQuery selector API was developed to be familiar to CSS developers…like us!


Example #3: Toggling a Popup Div

So let's try another example using selectors. Using the following HTML code:

  1. <!doctype html><!--[if lt IE 7]> <html lang="en"> <![endif]--><!--[if IE 7]> <html lang="en"> <![endif]--><!--[if IE 8]> <html lang="en"> <![endif]--><!--[if gt IE 8]><!-->
  2. <html class="no-js"lang="en"><!--<![endif]-->
  3. <head>
  4. <metacharset="utf-8">
  5. <metahttp-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <metaname="description" content="">
  7. <metaname="author" content="">
  8. <metaname="viewport" content="width=device-width">
  9. <link rel="stylesheet" href="css/style_03.css">
  10. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body id="tmpDialogueExample" >
  13. <form action="javascript:void(0);" method="post">
  14. <p> In jQuery, the selector API allows you to select elements from the DOM, just like you do in CSS stylesheets. This simple dialogue contains a few selector API examples. </p>
  15. <p>
  16. <input type="submit" name="tmpDialogueOpen" id="tmpDialogueOpen" value="Open Dialogue" />
  17. </p>
  18. <div id="tmpDialogue" >
  19. <input type="submit" name="tmpDialogueClose" id="tmpDialogueClose" value="Close Dialogue" />
  20. </div>
  21. </form>
  22. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js" ></script>
  23. <script>window.jQuery ||document.write("<script src='js/libs/jquery-3.1.1.min.js'><\/script>")</script>
  24. <script src="js/plugins.js"></script>
  25. <script src="js/script_03.js"></script>
  26. </body>
  27. </html>


and the following styles in a css/style_03.css file:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body {
  4. font: 16pxsans-serif;
  5. }
  6.  
  7. div#tmpDialogue {
  8. display: none;
  9. position: absolute;
  10. top: 50%;
  11. left: 50%;
  12. width: 500px;
  13. height: 500px;
  14. margin: -251px 0 0-251px;
  15. border: 1px solid blue;
  16. background: lightblue; }
  17.  
  18. body#tmpDialogueExample div.tmpDialogueOn { display: block; }
  19.  
  20. input#tmpDialogueClose {
  21. position: absolute;
  22. bottom: 5px;
  23. right: 5px;
  24. width: 100px;
  25. }


In our script_03.js file, place the following javascript:

  1. // JavaScript Document
  2. var tmpExample ={
  3. ready : function(){
  4. $('input#tmpDialogueOpen').click(
  5. function($e){
  6. $e.preventDefault();
  7. $('div#tmpDialogue').addClass('tmpDialogueOn');
  8. }
  9. );
  10. $('input#tmpDialogueClose').click(
  11. function($e){
  12. $e.preventDefault();
  13. $('div#tmpDialogue').removeClass('tmpDialogueOn');
  14. }
  15. );
  16. }
  17. };
  18.  
  19. $(document).ready(tmpExample.ready);

Example 3: Explained

On the surface, the above example works similar to the previous example: the jQuery ready function is called after the document loads. Chained to this ready function is our custom tmpExample.ready function. This function does two things:

1.)It attaches a jQuery click() event function to the first submit button in the HTML, labeled with the #tmpDialogueOpen ID attribute. This click function takes as its parameter an anonymous function. The event object ($e) is passed to it so that we can prevent the default action of this event: $e.preventDefault();. Finally, we add a class to the tmpDialogue div. 

This new class, you may notice, simply unhides the div#tmpDialogue, set to display:none; in the css.

2.)tmpExample.ready also attaches a second click() event, as seen in the code above. This event does something similar to the previous click() event, but in this case it is attached the submit button labelled #tmpDialogueClose, and it removes the .tmpDialogueOn class from the #tmpDialogue div. As #tmpDialogue's native style is to display none, this line of code essentially re-hides it.

The result is something like a kind of toggling popup window:

Screen Shot 2012-04-14 at 5.07.09 PM


Example #4: Refining Selectors

One more example, this time a little more advanced. [Click here] to see it in action. You can find the code [

Example #4: Explained

The HMTL is fairly straightforward: Two unnumbered lists and a section of links below it. Upon closer inspection, you will notice that nearly every tag is classed and/or IDed. For example: <ul id='tmpPlants'> and <li class='tmpVegetables' id='tmpOnion'>Onion</li>.

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  8. <meta name="description" content="">
  9. <meta name="author" content="">
  10. <meta name="viewport" content="width=device-width">
  11. <link rel="stylesheet" href="css/style.css">
  12. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  13. </head>
  14. <body id='tmpDialogueExample'>
  15. <div id='tmpSelection'>
  16. <div class='tmpList'>
  17. <h4>Edible Plants</h4>
  18. <ul id='tmpPlants'>
  19. <li class='tmpVegetables' id='tmpOnion'>Onion</li>
  20. <li class='tmpVegetables' id='tmpBroccoli'>Broccoli</li>
  21. <li class='tmpVegetables' id='tmpPepper'>Pepper</li>
  22. <li class='tmpVegetables' id='tmpCarrot'>Carrot</li>
  23. <li class='tmpFruits'>Apple</li>
  24. <li class='tmpFruits'>Cherry</li>
  25. <li class='tmpFruits' id='tmpOrange'>Orange</li>
  26. <li class='tmpFruits'>Lemon</li>
  27. </ul>
  28. </div>
  29. <div class='tmpList'>
  30. <h4>Animals</h4>
  31. <ul id='tmpAnimals'>
  32. <li id='tmpChicken'>Chicken</li>
  33. <li id='tmpCow'>Cow</li>
  34. <li id='tmpBuffalo'>Buffalo</li>
  35. <li id='tmpSheep'>Sheep</li>
  36. <li id='tmpRabbit'>Rabbit</li>
  37. </ul>
  38. </div>
  39. </div>
  40. <div id='tmpRecap'>
  41. <p>
  42. <a href='#' id='tmpFind'>
  43. Find all &amp;lt;li&amp;gt; elements inside of &amp;lt;ul&amp;gt; elements.
  44. </a>
  45. </p>
  46. <p>
  47. <a href='#' id='tmpSiblings'>
  48. Find all siblings of the &amp;lt;li&amp;gt; element with id tmpCarrot.
  49. </a>
  50. </p>
  51. <p>
  52. <a href='#' id='tmpNext'>
  53. Select the &amp;lt;li&amp;gt; sibling element after the &amp;lt;li&amp;gt; element
  54. with id name tmpBroccoli.
  55. </a>
  56. </p>
  57. <p>
  58. <a href='#' id='tmpPrev'>
  59. Select the &amp;lt;li&amp;gt; sibling element before the &amp;lt;li&amp;gt; element
  60. with id name tmpBroccoli.
  61. </a>
  62. </p>
  63. <p>
  64. <a href='#' id='tmpNextAll'>
  65. Select all &amp;lt;li&amp;gt; sibling elements after the &amp;lt;li&amp;gt; element
  66. with id name tmpBroccoli.
  67. </a>
  68. </p>
  69. <p>
  70. <a href='#' id='tmpPrevAll'>
  71. Select all &amp;lt;li&amp;gt; sibling elements before the &amp;lt;li&amp;gt; element
  72. with id name tmpOrange.
  73. </a>
  74. </p>
  75. <p>
  76. <a href='#' id='tmpVegetables'>
  77. Select only &amp;lt;li&amp;gt; sibling elements before the &amp;lt;li&amp;gt;
  78. element with id name tmpOrange that are vegetables.
  79. </a>
  80. </p>
  81. <p>
  82. <a href='#' id='tmpParents'>
  83. Find the parent &amp;lt;div&amp;gt; element, with id tmpSelection.
  84. </a>
  85. </p>
  86. <p>
  87. <a href='#' id='tmpParent'>
  88. Find parent &amp;lt;ul&amp;gt; elements of &amp;lt;li&amp;gt; elements.
  89. </a>
  90. </p>
  91. <p>
  92. <a href='#' id='tmpChildren'>
  93. Find children &amp;lt;h4&amp;gt; elements of parent &amp;lt;div&amp;gt; elements with
  94. class name tmpList.
  95. </a>
  96. </p>
  97. <p>
  98. <a href='#' id='tmpNot'>
  99. Select children &amp;lt;li&amp;gt; elements of parent &amp;lt;ul&amp;gt; elements,
  100. except for vegetables.
  101. </a>
  102. </p>
  103. <p>
  104. <a href='#' id='tmpSlice'>
  105. Select &amp;lt;li&amp;gt; elements beginning with Cow and ending with Sheep.
  106. </a>
  107. </p>
  108. <p>
  109. <a href='#' id='tmpAdd'>
  110. Select all animal &amp;lt;li&amp;gt; elements, then add Pepper and Broccoli.
  111. </a>
  112. </p>
  113. <p>
  114. <a href='#' id='tmpEq'>
  115. Select all &amp;lt;li&amp;gt; elements, and reduce to only Buffalo.
  116. </a>
  117. </p>
  118.  
  119. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
  120. <script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.js"><\/script>')</script>
  121.  
  122. <script src="js/plugins.js"></script>
  123. <script src="js/script.js"></script>
  124. </body>
  125. </html>

This is done to achieve granular selection in jQuery (described below).


The CSS is also straightforward:

  1. body {
  2. font: 16px sans-serif;
  3. }
  4. ul {
  5. list-style: none;
  6. padding: 0;
  7. margin: 0;
  8. width: 200px;
  9. }
  10. li {
  11. padding: 3px;
  12. margin: 3px;
  13. }
  14. div.tmpList {
  15. float: left;
  16. margin: 0 20px;
  17. }
  18. div#tmpRecap {
  19. clear: left;
  20. padding: 10px;
  21. }
  22. .tmpExample {
  23. border: 1px solid rgb(200, 200, 200);
  24. background: #cbe5f8;
  25. }
  26. div#tmpSelection {
  27. overflow: hidden;
  28. }


The jQuery code, inside the script.js file, uses the same surface logic as the previous examples: creating an object with a ready function, then calling that object.function when the document is fully loaded:

  1. var tmpExample = {
  2. ready : function() {
  3. // Find all <input> elements and add a click
  4. // event.
  5. $('a').click(tmpExample.findElements);
  6. },
  7.  
  8. findElements : function($e)
  9. {
  10. // Prevent the default action, navigating to the link.
  11. $e.preventDefault();
  12.  
  13. // Reset the example before applying the next.
  14. $('*').removeClass('tmpExample');
  15.  
  16. switch (this.id)
  17. {
  18. case 'tmpFind':
  19. {
  20. // If the id of "this" <input> element contains "Find",
  21. // Do the find() example.
  22. $('ul').find('li').addClass('tmpExample');
  23. break;
  24. }
  25. case 'tmpSiblings':
  26. {
  27. $('li#tmpCarrot').siblings().addClass('tmpExample');
  28. break;
  29. }
  30. case 'tmpNext':
  31. {
  32. $('li#tmpBroccoli').next().addClass('tmpExample');
  33. break;
  34. }
  35. case 'tmpPrev':
  36. {
  37. $('li#tmpBroccoli').prev().addClass('tmpExample');
  38. break;
  39. }
  40. case 'tmpNextAll':
  41. {
  42. $('li#tmpBroccoli').nextAll().addClass('tmpExample');
  43. break;
  44. }
  45. case 'tmpPrevAll':
  46. {
  47. $('li#tmpOrange').prevAll().addClass('tmpExample');
  48. break;
  49. }
  50. case 'tmpVegetables':
  51. {
  52. $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');
  53. break;
  54. }
  55. case 'tmpParents':
  56. {
  57. $('li#tmpCarrot').parents('div#tmpSelection').addClass('tmpExample');
  58. break;
  59. }
  60. case 'tmpParent':
  61. {
  62. $('li').parent('ul').addClass('tmpExample');
  63. break;
  64. }
  65. case 'tmpChildren':
  66. {
  67. $('div.tmpList').children('h4').addClass('tmpExample');
  68. break;
  69. }
  70. case 'tmpNot':
  71. {
  72. $('ul li').not('li.tmpVegetables').addClass('tmpExample');
  73. break;
  74. }
  75. case 'tmpSlice':
  76. {
  77. $('ul#tmpAnimals li').slice(1, 4).addClass('tmpExample');
  78. break;
  79. }
  80. case 'tmpAdd':
  81. {
  82. $('ul#tmpAnimals li').add('li#tmpBroccoli, li#tmpPepper').addClass('tmpExample');
  83. break;
  84. }
  85. case 'tmpEq':
  86. {
  87. $('ul li').eq(10).addClass('tmpExample');
  88. break;
  89. }
  90. }
  91. }
  92. };
  93.  
  94. $(document).ready(tmpExample.ready);


It attaches a click() event to each link in the HTML, with the tmpExample.findElements function call passed as the click event parameter. This ensures that tmpExample.findElements function, defined below tmpExample.ready, is called whenever a link is clicked.

The Switch Statement

findElements() is actually pretty simply too, it just uses a code construct we haven't seen before: the switch statementSwitch statements are pretty universal throughout the programming world. They can be thought of as switchboards: the statement checks the given input value and, based on this value, fires off a specific set of instructions. In our example, the switch statement is looking for the ID of whatever link called the findElements() function:

switch (this.id)Then the statement defines eventualities for every link ID case we're interested in with case statements. Every case statement ends with the break; command. This exits the case, thereby exiting the switch statment as well. Some examples of the case statements in our code: 


case 'tmpSiblings':{   $('li#tmpCarrot').siblings().addClass('tmpExample');   break;}

–and–

case 'tmpVegetables':{ $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');   break;} These cases simply add the .tmpExample class to specific list items, but notice how jQuery is going about selecting them: siblings(), prevAll(), children(), parents(), etc. These methods allow you to search and filter the selection results you obtain. More on this below.


A Rundown of the jQuery Filters

The previous example is really designed to show you all of the jQuery Selector API's filtering functions in a single script. Let's examine each on a case by case basis.

find(): The find() method lets you search for elements within a selection you’ve already made. Below, we select all ul tags, then find() all li tags within them so we can add the .tmpExample class to each one:


  case 'tmpFind':
{
// If the id of "this" <input> element contains "Find",
// Do the find() example.
   $('ul').find('li').addClass('tmpExample');
   break;
}


siblings(): The siblings() method lets you select all elements on the same hierarchical level as your main selection, in this case all other list items in the same list as <li id="tmpCarrot">:

case 'tmpSiblings':
{
   $('li#tmpCarrot').siblings().addClass('tmpExample');
   break;
}

next(): The next() method lets you select the next sibling element in the HTML document:

case 'tmpNext':
{
   $('li#tmpBroccoli').next().addClass('tmpExample');
break;
}

prev(): Similar to next(), the prev() method lets you select the preceding sibling element in the HTML document:

case 'tmpPrev':
{
   $('li#tmpBroccoli').prev().addClass('tmpExample');
   break;
}


nextAll() and prevAll(): these two methods work similarly to next() and prev(), except they select all sibling elements after and before your main selection respectively: 

case 'tmpNextAll':
{
   $('li#tmpBroccoli').nextAll().addClass('tmpExample');
break;
}
case 'tmpPrevAll':
{
   $('li#tmpOrange').prevAll().addClass('tmpExample');
   break;
}


This instance of the prevAll() method has been passed a parameter, which further narrows its searching power to only select those previous siblings of #tmpOrange that happened to have the .tmpVegetables class:

case 'tmpVegetables':
{
   $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');
   break;
}

parents(): not surprisingly, parents() selects all parents of a selected element. In this example, however, parents() is being passed a selector for the tmpSelection div, further narrowing it to just that parent: 

case 'tmpParents':
{
   $('li#tmpCarrot').parents('div#tmpSelection').addClass('tmpExample');
   break;
}

parent(): Note that parent() is different than parents() in that it only selects the most immediate parent of the select element:

case 'tmpParent':
{
   $('li').parent('ul').addClass('tmpExample');
break;
}

children(): this method can be used to select specific children elements of a selected element, in this case all h4 tags in the tmpList div: 

case 'tmpChildren':
{
   $('div.tmpList').children('h4').addClass('tmpExample');
   break;
}

not(): The not() method allows to essentially deselect specific elements. In the case below, we want to select all list items, except those with the .tmpVegetables class: 

case 'tmpNot':
{
   $('ul li').not('li.tmpVegetables').addClass('tmpExample');
   break;
}


slice(): this method takes a beginning index value and ending index value as its parameters, allowing you to select a range of elements within a selection. 

case 'tmpSlice':
{
   $('ul#tmpAnimals li').slice(1, 4).addClass('tmpExample');
   break;
}


add(): The add() method allows to make a selection and then add elements to it, useful for constructing complicated selections of elements. Below we make a standard jQuery selection of all list items in the tmpAnimals unnumbered list, then we add the tmpBroccoli and tmpPepper list items.

case 'tmpAdd':
{
   $('ul#tmpAnimals li').add('li#tmpBroccoli, li#tmpPepper').addClass('tmpExample');
   break;
}


eq(): this method allows you to reduce a selection based on its index number. In the following example, we select all list items, which returns an array of all list items in the DOM. The then eq() method is chained to our selection and passed an index number of 10. Because indexes always start at 0, eq(10) selects the 11th list item in the DOM, i.e. "Buffalo": 

case 'tmpEq':
{
   $('ul li').eq(10).addClass('tmpExample');
   break;
}



Events in jQuery

Not surpisingly, event handlers in any programming language exist to deal with events: mouse clicks, mouse moves, drags, drops. In short, user interaction. Creating event handlers in oldschool JavaScript used to be really difficult, but jQuery makes it much easier. There are a few ways to deal with events in jQuery, but the bind() method is by far the easiest. 

The bind() method accepts two parameters: 

  1. the event name, such as ‘ready’, ‘mouseover’, ‘mouseout’, or ‘click’  
  2. a function call or anonymous function declaration (i.e. the entire body of the function is passed in as one lone parameter) 
Try the following example:

Example 5: the jQuery bind() method

[click here to see example 5 in action] [click here to download the Example 05 files]

 The bind() method simply attaches some other function or method to a particular event. In the case below, we have a very basic HTML5 document:

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8. <meta name="description" content="">
  9. <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10. <link rel="stylesheet" href="css/style.css">
  11. <script src="/js/libs/modernizr-2.5.3.min.js"></script>
  12. </head>
  13. <body>
  14. <div></div>
  15. <div></div>
  16. <div></div>
  17. <div></div>
  18. <div></div>
  19. <div></div>
  20. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
  21. <script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js"><\/script>')</script>
  22. <script src="js/plugins.js"></script>
  23. <script src="js/script.js"></script>
  24. </body>
  25. </html>


And some simple CSS:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. div {
  4. border: 1px solid rgb(200, 200, 200);
  5. width: 100px;
  6. height: 100px;
  7. margin: 5px;
  8. float: left;
  9. }
  10. div.tmpExampleOver {
  11. background: #5092c5;
  12. }
  13. div.tmpExampleOn {
  14. background: #165b91;
  15. }


and the following  jQuery code in our script.js file:

  1. // JavaScript Document
  2. $(document).bind(
  3. 'ready',
  4. function() {
  5. $('div').bind(
  6. 'mouseover',
  7. function() {
  8. $(this).addClass('tmpExampleOver');
  9. }
  10. );
  11.  
  12. $('div').bind(
  13. 'mouseout',
  14. function() {
  15. $(this).removeClass('tmpExampleOver');
  16. }
  17. );
  18.  
  19. $('div').bind(
  20. 'click',
  21. function() {
  22. if ($(this).hasClass('tmpExampleOn')) {
  23. $(this).removeClass('tmpExampleOn');
  24. } else {
  25. $(this).addClass('tmpExampleOn');
  26. }
  27. }
  28. );
  29.  
  30. }
  31. );


The resulting index.html file, rendered in a browser, should look something like this:

example 05

[click screenshot to see the actual page in a browser]

As you can see, the six divs change background color as you hover the mouse over them (mouseover events), change back to their original background color when the mouse moves out (mouseout events) and toggles a dark blue background color when you click on any of them(click event). Let’s see how it works, shall we? 

Example 5: Explained

The HTML and CSS is fairly straightforward: six anonymous divs in the HTML, styled as six squares by the CSS. The CSS also has two additional classes: they add background colors for the mouseover state and the clicked state, respectively:

div.tmpExampleOver {
    background: #5092c5;
}

div.tmpExampleOn {
    background: #165b91;
}

 As per usual, the jQuery is where the interaction happens. The first thing that occurs is a use of the bind() method to attach further functions to the entire document when the ready event is detected:

$(document).bind( 'ready', ...)


The bind() method accepts two parameters: 1.)the event name, in this case ready and 2.) a function call or anonymous function declaration. We’ll be passing an entire anonymous function as one big parameter. The function we’re passing is really just three simple subroutines:

1.)To each div tag we’re binding a mouseover event function that adds the tmpExampleOver upon detecting any mouse over event:

    $('div').bind( 'mouseover',
        function() {
        $(this).addClass('tmpExampleOver');
      }
    );

2.)Then to each div we’ll bind an event that essentially undoes what we just did when the mouse leaves the div area: 

    $('div').bind(  'mouseout',
      function() {
        $(this).removeClass('tmpExampleOver');
      }
    );

And finally we’ll bind a click event to each div that adds tmpExampleOn class if it isn’t attached, and removes the class if it is attached: 

    $('div').bind(
      'click',
      function() {
        if ($(this).hasClass('tmpExampleOn')) {
          $(this).removeClass('tmpExampleOn');
        } else {
          $(this).addClass('tmpExampleOn');
        }
      }
    );


Advanced Event Handling 

As I said before, there a plenty of interesting ways to handle events in jQuery. The following example covers four of them:

Example 6: Advanced Event Handling Examples

[click here to play with this example in a browser] [click here to get the example code]

The HTML and CSS for this example is very similar to that of example 05 above, i.e. some anonymous divs styled to be 100px by 100px squares. The code found in the script.js file provides four different examples of the innovative and simple ways to deal with events. Each of these functions is declared when the document has loaded via this line of jQuery:

$(document).ready( function(){...});

Let’s examine each example. The first uses the standard bind() method we used in the previous example, but notice that it combines, or chains, three bind() methods together like so: $('div.tmpBind').bind(...).bind(...).bind(...); You may also notice that we’re using the find() method to find all children div tags within the div.tmpBind.

EXAMPLE 06.01:

  1. function() {
  2. //Example 06.01: handling events with the bind() method:
  3. $('div.tmpBind').bind(
  4. 'mouseover',
  5. function() {
  6. $(this).find('div').addClass('tmpExampleOver');
  7. }
  8. ).bind(
  9. 'mouseout',
  10. function() {
  11. $(this).find('div').removeClass('tmpExampleOver');
  12. }
  13. ).bind(
  14. 'click',
  15. function() {
  16. if ($(this).find('div').hasClass('tmpExampleOn')) {
  17. $(this).find('div').removeClass('tmpExampleOn');
  18. } else {
  19. $(this).find('div').addClass('tmpExampleOn');
  20. }
  21. }
  22. );
  23. //end of Example 01// JavaScript Document

Rather than bind(), Example 06.02 uses jQuery’s mouseover()mouseout(), and click() methods directly to add event functions, chaining them together like so:

$('div.tmpIndividual').mouseover(...).mouseout(...).click();

EXAMPLE 06.02:


  1. $('div.tmpIndividual').mouseover(
  2. function() {
  3. $(this).find('div').addClass('tmpExampleOver');
  4. }
  5. ).mouseout(
  6. function() {
  7. $(this).find('div').removeClass('tmpExampleOver');
  8. }
  9. ).click(
  10. function() {
  11. if ($(this).find('div').hasClass('tmpExampleOn')) {
  12. $(this).find('div').removeClass('tmpExampleOn');
  13. } else {
  14. $(this).find('div').addClass('tmpExampleOn');
  15. }
  16. }
  17. );
  18. //end of Example 02


Example 06.03 uses the very convenient jQuery hover() and toggle() methods.

The hover() methods takes two functions as parameters, following this pattern:

$(‘the_element’).hover( the function to be called when the mouse is moved over the_element,  the function to be called when the mouse is moved away from the_element);

The toggle() method is similar, except it deals with clicks rather than mouseover events:

$(‘the_element’).toggle(the function to be called when the mouse is clicked on the_element,  the function to be called when the mouse is clicked a again on the_element);

EXAMPLE 06.03:

  1. $('div.tmpPattern').hover(
  2. function() {
  3. $(this).find('div').addClass('tmpExampleOver');
  4. },
  5. function() {
  6. $(this).find('div').removeClass('tmpExampleOver');
  7. }
  8. ).toggle(
  9. function() {
  10. $(this).find('div').addClass('tmpExampleOn');
  11. },
  12. function() {
  13. $(this).find('div').removeClass('tmpExampleOn');
  14. }
  15. );


And finally Example 06.04, which uses JavaScript methods focus() and blur() to deal with what happens when a browser gives focus (or removes it) from different user interface elements. In this case, we have a simple <textarea> tag. Users can ‘focus’ on things like textareas or input boxes by using the tab key on their keyboard, or by clicking on them directly. ‘blur’ refers to what happens when the user tabs away or clicks somewhere else. Using the focus() and blur() methods, we can define event functions for precisely this type of user interaction:

EXAMPLE 06.04:

  1. $('div.tmpTrigger textarea').focus(
  2. function($e) {
  3. $(this).addClass('tmpFocused');
  4. }
  5. ).blur(
  6. function() {
  7. $(this).removeClass('tmpFocused');
  8. }
  9. );
  10. $('div.tmpTrigger textarea').focus();
  11. }

Above we are essentially adding the class .tmpFocused when a user focuses on the textarea in div#tmpTrigger, then removing that class when focus is removed, or blurred, as it is called. Also notice the last line in the function: 

$('div.tmpTrigger textarea').focus();


This forces browser focus on our textarea. Just calling the focus() method on a focussable element like <textarea> will give it immediate focus in the browser. (Note that with HTML5, this can be done without any JavaScript at all, as it is a built-in property of the new HTML5 form elements. However, it’s always nice to have fallbacks.) 

Due December 19 

Project Requirements 

The final project class requires a little bit of research, trial and error, and testing. You are to choose a minimum of one jQuery plugin, either from the list below, or one of your own choosing, and try to implement it on your existing websites. The plugins listed below are just suggestions, and you are free to choose whatever you like from the world wide internetz, but please do let me know what you intend to implement before you start work!

Suggested plugins: 

A Word on Research

A good portion of this project is the research requirement. I have outlined some examples and suggestions above for what you could do for your project, but the real strength of your project will lay in its exploration of what's available online. The harder you look for answers to problems, the better grade you will get.

Project Submission: Send me a link!

Final projects are due, uploaded to the schwittek.com server and the URL emailed to me, by Dec. 19, end of day.

CGI/ART 222 – Applied Imaging and Applications to the World Wide Web II

Advanced methods of two-dimensional graphics, image processing, and World Wide Web design leading to team projects in the fields of science and art. The purpose of this course is to learn the technics needed to hand-coding HTML5 and CSS3, as well as gain familiarity in JavaScript and current trends in JavaScript frameworks, server-side scripting, and Content Management Systems. Topics covered will include: HTML tags, Cascading Style Sheets (CSS) and tricks, JavaScript/JQuery and possibly PHP/MySQL, and Content Management Systems.

In life I try to be very lax about rules. In fact, you'll learn in this class that design rules should definitely be broken whenever possible, just to make things interesting. But this does not apply to the class itself, and I have a few rules that you must follow, listed in order of importance:

“Wait, no software or textbooks?! You straight trippin!” Actually, I’m not tripping.  The cool thing about the Web is that is was designed to run on different types of servers, subsist of nothing more than text documents (and the occasional image or video) and was developed as an open source movement by some pretty smart people who didn’t want HTML to be owned by anyone. This means that all the information, most of the code and the software needed to use the Web, and develop the Web, are on the Web – for free: 

Here are some resources:


Therefore, in this class, I’m not requiring you to purchase software or textbooks. However, if you feel like spending some duckets, you may be interested in the following items:

Software:

Adobe Dreamweaver ($449.00): This program is designed to be a WYSIWYG (What You See is What You Get) HTML, PHP, CSS, JavaScript and other code editing program. Unfortunately, dynamic content can look different pretty much anywhere it’s vewed – cause it’s dynamic, and all – and therefore does not translate well from a static, word processor like authoring program. In other words, “Dreamweaver writes crappy code.” 

That said, there are some god things about Dreamweaver that make it an all around good solution. However, it costs money and there are free solutions (below).

Aptana Studio (Free, Mac+PC): I just discovered this little gem and I think it’s pretty amazing. It can be used to edit all kinds of code, but we can use it to edit HTML, CSS and JavaScript. It’s free, open source and available for all platforms, so everyone of us should have no excuse for missing work.  http://aptana.com/

FileZilla (Free, Mac+PC): So both Dreamweaver and Aptana have FTP clients in them, but I think we should keep things separate for the time being. FTP stands for File Transfer Protocol and it is how we put and get things on and off of a file servers. And yes, put and get are indeed technical terms. Isn’t the Internet wonderful?  http://filezilla-project.org/


 Hardware: you won’t need much in the way of technology for this class. A 4GB thumb drive will pretty much do it. On this drive you are going to store code editing software, various browsers and, of course, code. Thumbdrives have a habit of breaking or getting lost, so they shouldn’t be a permanent repository for your files and applications, just a portable, temporary solution. An added bonus? You can swallow thumbdrives if the Feds break down your door! Just kidding (not really, though).  

  • Texts: Books about the Internet generally have one major flaw: they tend to be out of date after only a few years. However, some people just work better when they have a hunk of dead tree in their bag. Therefore, if you must purchase a reference textbook, might I suggest the following:
    • HTML & XHTML: The Definitive Guide, 6th Edition, by By Chuck Musciano, Bill Kennedy. Publisher: O'Reilly Media. Released: October 2006. This book covers the basics of HTML all the way up to just before HTML5, and thus contains an excellent reference of the basics. Think of this book as the Old Testament and any future books you buy as parts of the New Testament. With this in mind, check out the next book:
    •  HTML5: Up and Running, By Mark Pilgrim, Publisher: O'Reilly Media Released: August 2010. This book covers the sordid history of the HTTP and HTML standards, the browser wars of the nineties, and how we got to HTML. It then proceeds to cover almost every new thing about HTML and  how JavaScript and CSS interact with it. The second half of the class, people! Yippee!
    • Pro HTML5 Programming: Powerful APIs for Richer Internet Application Development, by Peter Lubbers Brian Albers Frank Salim. Publisher: Apress, 2010. This book is very cool, and we may dig into it to find a very cool project incorporating HTML5, CSS3 and JavaScript/JQuery. 

Welcome to Art 222 – Applied Imaging and Applications to the World Wide Web II

Class 1: Welcome to class! We have a lot to cover, so let's disucss what this class is all about!

  • Who am I?
  • What is this course all about? And why the mysteriously long name: Applied Imaging and Applications to the World Wide Web II?
  • What is the Web, what is the Internet, and what is a URL?

Review of HTML

  • What is it, what's it look like and how do I begin?
  • Basic Structure: 
    • <!DOCTYPE>
    • <head>
    • <body>
    • The DOM (Document Object Model)

DOM-diagram

    • Basic sytnax and structural tags
      • <p>
      • <div>
      • <span>
      • <li> and <ol>
      • <hr />
      • <div>
      • <span>
      • <form> and associated tags
      • <input>
        • Checkbox, Radio button, Drop-down, etc.
        • <textarea>
        • <button>
        • <select>
        • <option>
        • <optgroup>
        • <fieldset>
        • <label>
    • HTML attributes


URL Structure

What's URL and why they sometimes suck?

  • scheme://domain:port/path?query_string#fragment_id
  • The scheme we're using it HTTP (HyperText Transfer Protocol) or HTTPS (Secure HyperText Transfer Protocol)
  • A domain is something like "art.lehman.edu", the port is always 80, which the browsers assumes. This section could also be an IP address of the host machine.
  • Immediatly following the domain, after the  / is the filepath, similar to filepaths on any other device. This is what the server uses to find the document being referenced.
  • the ?query#fragment_id refers to any variables that are being passed in the URL and an anchor position in the target document


In Class Exercise

 

 


Reviewing CSS: Cascading Style Sheets

Cascading Style Sheets (CSS) have revolutionized the way designers work with HTML. In brief, CSS syntax gives browsers a set of instructions on how to display HTML elements on a page. W3C, the peeps in charge of defining and maintaining global web standards, define CSS as "a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, in speech, etc." Instead of placing visual structure and styling intructions inside each HTML document, the instructions can now be placed externally, in a single place. Don't think that's interesting? Ok, let's try styling HTML the old-fashioned way...

Styling without CSS

  • bold
  • italics
  • colors
  • boxes
  • font tag 

Benefits of Using CSS

Example: Styling a paragraph

CSS Structure

CSS Syntax
SelectorDeclarationDeclaration
p
{text-decoration: underline; padding: 15px;}
  property value property value

 

CSS inclusion methods

  • inline
  • embedded
  • external

In class exercise: 

1.) Create an HTML and an CSS document and link them together using the <link> tag method.  

2.) Create a class in CSS, invoke in HMTL.  

3.) Add some basic content to the HTML document. Be sure to include the following, properly structured:

  • <div> tag to separate the main content area
  • <p> tags for paragraphs
  •  <h1> and other header tags for content headings
  • <img>: throw a few images into the content!

4.) Add some basic navigation using the <ul> and/or <ol> tags

 

Styling the content

Now that we have some basic content, let's begin to style some of it.

  • Try to center the content by giving the <body> tag margins % values
    • e.g. body
      {margin-left: 15%; margin-right: 15%; }
  • Define some colors: hex, RGB(), named colors...
  • use some <a> pseudoclasses
    • a:link { text-decoration: none; color: rgb(0, 0, 153) }
    • a:visited { text-decoration: none; color: rgb(153, 0, 153) }
    • a:hover { text-decoration: underline; color: rgb(0, 96, 255) }
    • a:active { text-decoration: none; color: rgb(255, 0, 102) }

Other CSS Details

  • CSS inheritance
  • Classes and ID
  • Over-riding inheritance with classes (dot notation)
  • Images in CSS
  • Box model:

boxdim

In Class Exercise: Create a basic CSS-styled HMTL document

Using what we about HTML and CSS, let's create a basic CSS-styled HTML document. Just as a review, the steps are as follows:

  1. create basic HTML5 document
  2. create CSS
  3. link the both the HTML and CSS document
  4. Let's place something in the HTML body
    1. For navigation, use these tags
      1. <nav>
      2. <h2>
      3. <ul> and <li>
    2. For content, use the following tags:
      1. <div>
      2. <h1>
      3. <p>
  5. Using CSS, try to get your document to look like this:

Screen Shot 2016-08-11 at 9.21.51 PM

Extra Credit!!!

For extra credit, use FontSquirrel or similar to embed your font.

Reveiwing the in Class Exercise: Creating a basic CSS-styled HMTL document

Let's review how to make the styled HTML document below: 

Screen Shot 2016-08-11 at 9.21.51 PM

Embedding Fonts

Let's look at how we can use FontSquirrel (or similar) to embed your font.

Wireframes

Finally, let's look at your wireframes and spend the remainder of class refineing them.

JavaScript! Yay!!!

So, we've finally gotten to the portion of the class where we get to work with JavaScript. JavaScript is a browser or client-side, interpretive, scripting language that has been around since 1995, when it was called LiveScript and it was maintained by the browser company Netscape as a way of adding interactivity to web pages. We're going to be exploring JavaScript via jQuery, a very popular JavaScript framework that is currently blowing up huge. 

framework, in this sense, is a comprehensive library of shortcut methods (a.k.a. functions) and objects that are all built with JavaScript. In other words, developers took many of the functions and classes they had already been using in JavaScript, stuck them all in a single library file, and made them accessible with shortcut syntax that we call jQuery.

Example #1

We'll start with a simple example. Create an HTML doc with the following code and call it index.html:

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8. <meta name="description" content="">
  9. <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10. <link rel="stylesheet" href="css/style.css"> <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body>
  13. <p>
  14. jQuery is not loaded.
  15. </p>
  16. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
  17. <script>window.jQuery || document.write('<script src="js/libs/jquery-3.1.0.js"><\/script>')</script> <script src="js/plugins.js"></script>
  18. <script src="js/script.js"></script>
  19. </body>
  20. </html>



Then create the following CSS file and name it style.css:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body { font: 16px sans-serif; }
  4.  
  5. p { color: red; border: 1px solid red; padding: 5px; margin: 5px; }
  6.  
  7. p.tmpFrameworkLoaded { color: green; border: 1px solid green; }


and place the following JavaScript in a js/script.js file:

  1. // JavaScript Document
  2. if ($) {
  3.  
  4. $(document).ready( function() {
  5.  
  6. $('p').addClass('tmpFrameworkLoaded');
  7.  
  8. $('p').text('jQuery successfully loaded and running!');
  9.  
  10. } );
  11.  
  12. }

Example #1 in action

In the previous code, we created a simple HTML5 document with nothing special in the body: 

<p>jQuery is not loaded.</p>

But if we then load this into a browser, we will see the following:  

jquery not loaded

This shouldn't be all that suprising, since that message appears in the HTML. But the jQuery code we place in script.js should have given us the following: 

jquery loaded

This example is a simple test to see if jQuery has loaded properly. Since we didn't download the jQuery library, it should be no surprise that it doesn't work. Downloading jQuery is easy: simply go to the  jQuery.com download section and download the most recent version (compressed or uncompressed – it doesn't matter, though compressed is smaller in size and, therefore, loads faster).  Whichever version you have, you'll see that it is contained inside a single JavaScript file. This file should be saved into a js/libs folder like so:

jquery install
Once you have installed (a.k.a. saved) jQuery, open up your index.html file in a browser again to test it.


Example #1 Explained

So here's what is going on the previous example. The HTML is pretty simple: just a simple <p> tag with a default message in it. In the CSS file we created, this simple style declaration:

p { color: red; border: 1px solid red; padding: 5px; margin: 5px; }

which applies to all <p> tags in the HTML document, including the aforementioned <p> tag, and the message text within it. In the script.js file we have the following code: 


$('p').addClass('tmpFrameworkLoaded');This code uses the jQuery object selector ($) and, in this case, it is selecting all HTML <p> elements in the DOM. It is then calling the jQuery addClass function on all <p> tags. This nifty function simply attaches CSS classes to whatever elements it is "chained" to.  The class that is attached is passed as a parameter to the addClass function, adding to (and, in this case, overiding) whatever styles the tag had prior. In this case the class is .tmpFrameworkLoaded , the definition of which is defined in our CSS file:

p.tmpFrameworkLoaded { color: green; border: 1px solid green; }

The next line of jQuery uses the jQuery text function to change the text within all <p> and </p> tags to whatever string of characters is passed as a parameter: 

$('p').text('jQuery successfully loaded and running!'); 

If jQuery has indeed been loaded successfully, the $s, the addClass and text functions, and all the other jQuery syntax in our script.js file should work and we will be presented with an HTML document, altered directly in the browser, to look like this:

jquery loaded


How Is This Better Than Good Ole' JavaScript? 

I'm so glad you asked! Well, this is a simple example – realy only a couple of choice lines – that changes a few things around in our DOM (Document Object Model).  As simple as it is, however, if we wanted to do the same thing using standard JavaScript, with no APIs or frameworks, it would look like this:

  1. // JavaScript Document
  2. window.onload = function() {
  3.  
  4. var $p = document.getElementsByTagName('p')[0];
  5.  
  6. $p.className = 'tmpFrameworkLoaded';
  7.  
  8. if($p.innerText) {
  9.  
  10. $p.innerText = 'jQuery successfully loaded and running!';
  11.  
  12. } else {
  13.  
  14. $p.textContent = 'jQuery successfully loaded and running!';
  15.  
  16. }
  17.  
  18. };

Yikes! Variable declarations?! getElementsBy TagName?! If/else statements?! That code is a hot mess! However, before jQuery was invented in 2006, this was the only way to do it. 


So What Makes jQuery Better? 

One thing that makes jQuery far easier to implement than standard Javascript is its selectors API. We're already quite familar with the concept of a selector: we've been using them constantly in our CSS files. In the following code snippet, bodya, and .highlight and all selectors:

body{ padding: 0px; margin: 0px; background: url("/images/bg.gif") #ccc no-repeat; }
a:link, a:hover{ color: red; }
.highlight{ color: black; background-color: yellow; }

As you can see, selectors are what CSS uses to reference HTML elements in general, and class names and ID tag specifically, with the intent of making them look and feel a certain way. In jQuery the concept is the same, but rather than determine styling,  jQuery determines behavior. Take the following HTML code...go on, literally take it, and save it as an HTML document.

Example #2: Controlling Links

  1. <!doctype html><!--[if lt IE 7]> <html lang="en"> <![endif]--><!--[if IE 7]> <html lang="en"> <![endif]--><!--[if IE 8]> <html lang="en"> <![endif]--><!--[if gt IE 8]><!-->
  2. <html class="no-js"lang="en"><!--<![endif]-->
  3. <head>
  4. <metacharset="utf-8">
  5. <metahttp-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <metaname="description" content="">
  7. <metaname="author" content="">
  8. <metaname="viewport" content="width=device-width">
  9. <link rel="stylesheet" href="css/style_02.css">
  10. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body>
  13. <ul id="tmpFavorites">
  14. <li><a href="<a href="http://www.google.com">Google</a></li>">http://www.google.com">Google</a></li></a>
  15. <li><a href="<a href="http://www.facebook.com">FaceBook</a></li>">http://www.facebook.com">FaceBook</a></li></a>
  16. <li><a href="<a href="http://www.apple.com">Apple</a></li>">http://www.apple.com">Apple</a></li></a>
  17. <li><a href="<a href="http://instagr.am/">Instagram</a></li>">http://instagr.am/">Instagram</a></li></a>
  18. </ul>
  19. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js" ></script>
  20. <script>window.jQuery ||document.write('<script src="js/libs/jquery-3.1.0.js"><\/script>')</script>
  21. <script src="js/plugins.js"></script>
  22. <script src="js/script_02.js"></script>
  23. </body>
  24. </html>

The HTML above contains a simple un-ordered list of common links. Nothing special... We're going to add a stylesheet containing the following code:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body { font: 16px sans-serif; }
  4.  
  5. ul {
  6. list-style: none;
  7. margin: 0;
  8. padding: 0;
  9. }
  10.  
  11. a{ text-decoration: none; }


and finally we're going to place the following jQuery code in our script.js file

  1. // JavaScript Document
  2. //create a new js object called tempExample
  3. var tmpExample = {
  4. //create a member method called ready
  5. ready : function(){
  6. // Find and return all links in ul#tmpFavorites, found in the jQuery object ($)...
  7. //attach a click event to each link
  8. $("ul#tmpFavorites li a").click(
  9. //pass the click event an anonymous function, with the event object ($e) as a parameter...
  10. function($e){
  11. //use the preventDefault() function to inhibit the default link click action
  12. $e.preventDefault();
  13. //and instead open a new browser window (or tab)
  14. window.open(this.href, "CoolLinks", ""); }
  15. //first parameter: the URL opened in the new window
  16. //second parameter: the name of the window or tab
  17. //third paramterL: a string containing window options, which we're leaving blank for now.
  18. );
  19. }
  20. };
  21. /*the above object and function doesn't get called until the entire document, and thus the DOM, has loaded. To make sure of this, we'll pass a reference to the tmpExample's ready function using the built-in jQuery $(document).ready*/
  22.  
  23. $(document).ready(tmpExample.ready);

Example #2: Explained

The jQuery code above is fully commented, but here is a rundown of what it's doing: 1.) The tmpExample object is created, along with a member method entitled ready. Then it just sits there in memory. 2.) As soon as the DOM is fully loaded, jQuery calls the $(document).ready() function we placed inside our script.js file. But notice we also passed it a reference to the tmpExample.ready object method, declared above. 3.) Because we did this, the browser will also execute this code.   

This example demonstrates the essence of the jQuery selector API: after the DOM is fully loaded into the browser's memory, this bit of code: 
<span style="line-height: 22.4px;">$(‘ul#tmpFavorites li a’).click()</span>

uses the main jQuery selector ($) and then more specifically selects all links with each list item of the unnumbered list with the #tmpFavorites ID. It looks a lot like CSS, and this is not a coincidence: the jQuery selector API was developed to be familiar to CSS developers…like us!


Example #3: Toggling a Popup Div

So let's try another example using selectors. Using the following HTML code:

  1. <!doctype html><!--[if lt IE 7]> <html lang="en"> <![endif]--><!--[if IE 7]> <html lang="en"> <![endif]--><!--[if IE 8]> <html lang="en"> <![endif]--><!--[if gt IE 8]><!-->
  2. <html class="no-js"lang="en"><!--<![endif]-->
  3. <head>
  4. <metacharset="utf-8">
  5. <metahttp-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <metaname="description" content="">
  7. <metaname="author" content="">
  8. <metaname="viewport" content="width=device-width">
  9. <link rel="stylesheet" href="css/style_03.css">
  10. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  11. </head>
  12. <body id="tmpDialogueExample" >
  13. <form action="javascript:void(0);" method="post">
  14. <p> In jQuery, the selector API allows you to select elements from the DOM, just like you do in CSS stylesheets. This simple dialogue contains a few selector API examples. </p>
  15. <p>
  16. <input type="submit" name="tmpDialogueOpen" id="tmpDialogueOpen" value="Open Dialogue" />
  17. </p>
  18. <div id="tmpDialogue" >
  19. <input type="submit" name="tmpDialogueClose" id="tmpDialogueClose" value="Close Dialogue" />
  20. </div>
  21. </form>
  22. <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js" ></script>
  23. <script>window.jQuery ||document.write("<script src='js/libs/jquery-3.1.0.js'><\/script>")</script>
  24. <script src="js/plugins.js"></script>
  25. <script src="js/script_03.js"></script>
  26. </body>
  27. </html>


and the following styles in a css/style.css file:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. body {
  4. font: 16pxsans-serif;
  5. }
  6.  
  7. div#tmpDialogue {
  8. display: none;
  9. position: absolute;
  10. top: 50%;
  11. left: 50%;
  12. width: 500px;
  13. height: 500px;
  14. margin: -251px 0 0-251px;
  15. border: 1px solid blue;
  16. background: lightblue; }
  17.  
  18. body#tmpDialogueExample div.tmpDialogueOn { display: block; }
  19.  
  20. input#tmpDialogueClose {
  21. position: absolute;
  22. bottom: 5px;
  23. right: 5px;
  24. width: 100px;
  25. }


In our scripts.js file, place the following javascript:

  1. // JavaScript Document
  2. var tmpExample ={
  3. ready : function(){
  4. $('input#tmpDialogueOpen').click(
  5. function($e){
  6. $e.preventDefault();
  7. $('div#tmpDialogue').addClass('tmpDialogueOn');
  8. }
  9. );
  10. $('input#tmpDialogueClose').click(
  11. function($e){
  12. $e.preventDefault();
  13. $('div#tmpDialogue').removeClass('tmpDialogueOn');
  14. }
  15. );
  16. }
  17. };
  18.  
  19. $(document).ready(tmpExample.ready);

Example 3: Explained

On the surface, the above example works similar to the previous example: the jQuery ready function is called after the document loads. Chained to this ready function is our custom tmpExample.ready function. This function does two things:

1.)It attaches a jQuery click() event function to the first submit button in the HTML, labeled with the #tmpDialogueOpen ID attribute. This click function takes as its parameter an anonymous function. The event object ($e) is passed to it so that we can prevent the default action of this event: $e.preventDefault();. Finally, we add a class to the tmpDialogue div. 

This new class, you may notice, simply unhides the div#tmpDialogue, set to display:none; in the css.

2.)tmpExample.ready also attaches a second click() event, as seen in the code above. This event does something similar to the previous click() event, but in this case it is attached the submit button labelled #tmpDialogueClose, and it removes the .tmpDialogueOn class from the #tmpDialogue div. As #tmpDialogue's native style is to display none, this line of code essentially re-hides it.

The result is something like a kind of toggling popup window:

Screen Shot 2012-04-14 at 5.07.09 PM


Example #4: Refining Selectors

One more example, this time a little more advanced. [Click here] to see it in action. You can find the code [

Example #4: Explained

The HMTL is fairly straightforward: Two unnumbered lists and a section of links below it. Upon closer inspection, you will notice that nearly every tag is classed and/or IDed. For example: <ul id='tmpPlants'> and <li class='tmpVegetables' id='tmpOnion'>Onion</li>.

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  8. <meta name="description" content="">
  9. <meta name="author" content="">
  10. <meta name="viewport" content="width=device-width">
  11. <link rel="stylesheet" href="css/style.css">
  12. <script src="js/libs/modernizr-2.5.3.min.js"></script>
  13. </head>
  14. <body id='tmpDialogueExample'>
  15. <div id='tmpSelection'>
  16. <div class='tmpList'>
  17. <h4>Edible Plants</h4>
  18. <ul id='tmpPlants'>
  19. <li class='tmpVegetables' id='tmpOnion'>Onion</li>
  20. <li class='tmpVegetables' id='tmpBroccoli'>Broccoli</li>
  21. <li class='tmpVegetables' id='tmpPepper'>Pepper</li>
  22. <li class='tmpVegetables' id='tmpCarrot'>Carrot</li>
  23. <li class='tmpFruits'>Apple</li>
  24. <li class='tmpFruits'>Cherry</li>
  25. <li class='tmpFruits' id='tmpOrange'>Orange</li>
  26. <li class='tmpFruits'>Lemon</li>
  27. </ul>
  28. </div>
  29. <div class='tmpList'>
  30. <h4>Animals</h4>
  31. <ul id='tmpAnimals'>
  32. <li id='tmpChicken'>Chicken</li>
  33. <li id='tmpCow'>Cow</li>
  34. <li id='tmpBuffalo'>Buffalo</li>
  35. <li id='tmpSheep'>Sheep</li>
  36. <li id='tmpRabbit'>Rabbit</li>
  37. </ul>
  38. </div>
  39. </div>
  40. <div id='tmpRecap'>
  41. <p>
  42. <a href='#' id='tmpFind'>
  43. Find all &amp;lt;li&amp;gt; elements inside of &amp;lt;ul&amp;gt; elements.
  44. </a>
  45. </p>
  46. <p>
  47. <a href='#' id='tmpSiblings'>
  48. Find all siblings of the &amp;lt;li&amp;gt; element with id tmpCarrot.
  49. </a>
  50. </p>
  51. <p>
  52. <a href='#' id='tmpNext'>
  53. Select the &amp;lt;li&amp;gt; sibling element after the &amp;lt;li&amp;gt; element
  54. with id name tmpBroccoli.
  55. </a>
  56. </p>
  57. <p>
  58. <a href='#' id='tmpPrev'>
  59. Select the &amp;lt;li&amp;gt; sibling element before the &amp;lt;li&amp;gt; element
  60. with id name tmpBroccoli.
  61. </a>
  62. </p>
  63. <p>
  64. <a href='#' id='tmpNextAll'>
  65. Select all &amp;lt;li&amp;gt; sibling elements after the &amp;lt;li&amp;gt; element
  66. with id name tmpBroccoli.
  67. </a>
  68. </p>
  69. <p>
  70. <a href='#' id='tmpPrevAll'>
  71. Select all &amp;lt;li&amp;gt; sibling elements before the &amp;lt;li&amp;gt; element
  72. with id name tmpOrange.
  73. </a>
  74. </p>
  75. <p>
  76. <a href='#' id='tmpVegetables'>
  77. Select only &amp;lt;li&amp;gt; sibling elements before the &amp;lt;li&amp;gt;
  78. element with id name tmpOrange that are vegetables.
  79. </a>
  80. </p>
  81. <p>
  82. <a href='#' id='tmpParents'>
  83. Find the parent &amp;lt;div&amp;gt; element, with id tmpSelection.
  84. </a>
  85. </p>
  86. <p>
  87. <a href='#' id='tmpParent'>
  88. Find parent &amp;lt;ul&amp;gt; elements of &amp;lt;li&amp;gt; elements.
  89. </a>
  90. </p>
  91. <p>
  92. <a href='#' id='tmpChildren'>
  93. Find children &amp;lt;h4&amp;gt; elements of parent &amp;lt;div&amp;gt; elements with
  94. class name tmpList.
  95. </a>
  96. </p>
  97. <p>
  98. <a href='#' id='tmpNot'>
  99. Select children &amp;lt;li&amp;gt; elements of parent &amp;lt;ul&amp;gt; elements,
  100. except for vegetables.
  101. </a>
  102. </p>
  103. <p>
  104. <a href='#' id='tmpSlice'>
  105. Select &amp;lt;li&amp;gt; elements beginning with Cow and ending with Sheep.
  106. </a>
  107. </p>
  108. <p>
  109. <a href='#' id='tmpAdd'>
  110. Select all animal &amp;lt;li&amp;gt; elements, then add Pepper and Broccoli.
  111. </a>
  112. </p>
  113. <p>
  114. <a href='#' id='tmpEq'>
  115. Select all &amp;lt;li&amp;gt; elements, and reduce to only Buffalo.
  116. </a>
  117. </p>
  118.  
  119. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
  120. <script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.js"><\/script>')</script>
  121.  
  122. <script src="js/plugins.js"></script>
  123. <script src="js/script.js"></script>
  124. </body>
  125. </html>

This is done to achieve granular selection in jQuery (described below).


The CSS is also straightforward:

  1. body {
  2. font: 16px sans-serif;
  3. }
  4. ul {
  5. list-style: none;
  6. padding: 0;
  7. margin: 0;
  8. width: 200px;
  9. }
  10. li {
  11. padding: 3px;
  12. margin: 3px;
  13. }
  14. div.tmpList {
  15. float: left;
  16. margin: 0 20px;
  17. }
  18. div#tmpRecap {
  19. clear: left;
  20. padding: 10px;
  21. }
  22. .tmpExample {
  23. border: 1px solid rgb(200, 200, 200);
  24. background: #cbe5f8;
  25. }
  26. div#tmpSelection {
  27. overflow: hidden;
  28. }


The jQuery code, inside the script.js file, uses the same surface logic as the previous examples: creating an object with a ready function, then calling that object.function when the document is fully loaded:

  1. var tmpExample = {
  2. ready : function() {
  3. // Find all <input> elements and add a click
  4. // event.
  5. $('a').click(tmpExample.findElements);
  6. },
  7.  
  8. findElements : function($e)
  9. {
  10. // Prevent the default action, navigating to the link.
  11. $e.preventDefault();
  12.  
  13. // Reset the example before applying the next.
  14. $('*').removeClass('tmpExample');
  15.  
  16. switch (this.id)
  17. {
  18. case 'tmpFind':
  19. {
  20. // If the id of "this" <input> element contains "Find",
  21. // Do the find() example.
  22. $('ul').find('li').addClass('tmpExample');
  23. break;
  24. }
  25. case 'tmpSiblings':
  26. {
  27. $('li#tmpCarrot').siblings().addClass('tmpExample');
  28. break;
  29. }
  30. case 'tmpNext':
  31. {
  32. $('li#tmpBroccoli').next().addClass('tmpExample');
  33. break;
  34. }
  35. case 'tmpPrev':
  36. {
  37. $('li#tmpBroccoli').prev().addClass('tmpExample');
  38. break;
  39. }
  40. case 'tmpNextAll':
  41. {
  42. $('li#tmpBroccoli').nextAll().addClass('tmpExample');
  43. break;
  44. }
  45. case 'tmpPrevAll':
  46. {
  47. $('li#tmpOrange').prevAll().addClass('tmpExample');
  48. break;
  49. }
  50. case 'tmpVegetables':
  51. {
  52. $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');
  53. break;
  54. }
  55. case 'tmpParents':
  56. {
  57. $('li#tmpCarrot').parents('div#tmpSelection').addClass('tmpExample');
  58. break;
  59. }
  60. case 'tmpParent':
  61. {
  62. $('li').parent('ul').addClass('tmpExample');
  63. break;
  64. }
  65. case 'tmpChildren':
  66. {
  67. $('div.tmpList').children('h4').addClass('tmpExample');
  68. break;
  69. }
  70. case 'tmpNot':
  71. {
  72. $('ul li').not('li.tmpVegetables').addClass('tmpExample');
  73. break;
  74. }
  75. case 'tmpSlice':
  76. {
  77. $('ul#tmpAnimals li').slice(1, 4).addClass('tmpExample');
  78. break;
  79. }
  80. case 'tmpAdd':
  81. {
  82. $('ul#tmpAnimals li').add('li#tmpBroccoli, li#tmpPepper').addClass('tmpExample');
  83. break;
  84. }
  85. case 'tmpEq':
  86. {
  87. $('ul li').eq(10).addClass('tmpExample');
  88. break;
  89. }
  90. }
  91. }
  92. };
  93.  
  94. $(document).ready(tmpExample.ready);


It attaches a click() event to each link in the HTML, with the tmpExample.findElements function call passed as the click event parameter. This ensures that tmpExample.findElements function, defined below tmpExample.ready, is called whenever a link is clicked.

The Switch Statement

findElements() is actually pretty simply too, it just uses a code construct we haven't seen before: the switch statementSwitch statements are pretty universal throughout the programming world. They can be thought of as switchboards: the statement checks the given input value and, based on this value, fires off a specific set of instructions. In our example, the switch statement is looking for the ID of whatever link called the findElements() function:

switch (this.id)Then the statement defines eventualities for every link ID case we're interested in with case statements. Every case statement ends with the break; command. This exits the case, thereby exiting the switch statment as well. Some examples of the case statements in our code: 


case 'tmpSiblings':{   $('li#tmpCarrot').siblings().addClass('tmpExample');   break;}–and–case 'tmpVegetables':{ $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');   break;} These cases simply add the .tmpExample class to specific list items, but notice how jQuery is going about selecting them: siblings(), prevAll(), children(), parents(), etc. These methods allow you to search and filter the selection results you obtain. More on this below.


A Rundown of the jQuery Filters

The previous example is really designed to show you all of the jQuery Selector API's filtering functions in a single script. Let's examine each on a case by case basis.

find(): The find() method lets you search for elements within a selection you’ve already made. Below, we select all ul tags, then find() all li tags within them so we can add the .tmpExample class to each one:


  case 'tmpFind':
{
// If the id of "this" <input> element contains "Find",
// Do the find() example.
   $('ul').find('li').addClass('tmpExample');
   break;
}


siblings(): The siblings() method lets you select all elements on the same hierarchical level as your main selection, in this case all other list items in the same list as <li id="tmpCarrot">:

case 'tmpSiblings':
{
   $('li#tmpCarrot').siblings().addClass('tmpExample');
   break;
}

next(): The next() method lets you select the next sibling element in the HTML document:

case 'tmpNext':
{
   $('li#tmpBroccoli').next().addClass('tmpExample');
break;
}

prev(): Similar to next(), the prev() method lets you select the preceding sibling element in the HTML document:

case 'tmpPrev':
{
   $('li#tmpBroccoli').prev().addClass('tmpExample');
   break;
}


nextAll() and prevAll(): these two methods work similarly to next() and prev(), except they select all sibling elements after and before your main selection respectively: 

case 'tmpNextAll':
{
   $('li#tmpBroccoli').nextAll().addClass('tmpExample');
break;
}
case 'tmpPrevAll':
{
   $('li#tmpOrange').prevAll().addClass('tmpExample');
   break;
}


This instance of the prevAll() method has been passed a parameter, which further narrows its searching power to only select those previous siblings of #tmpOrange that happened to have the .tmpVegetables class:

case 'tmpVegetables':
{
   $('li#tmpOrange').prevAll('li.tmpVegetables').addClass('tmpExample');
   break;
}

parents(): not surprisingly, parents() selects all parents of a selected element. In this example, however, parents() is being passed a selector for the tmpSelection div, further narrowing it to just that parent: 

case 'tmpParents':
{
   $('li#tmpCarrot').parents('div#tmpSelection').addClass('tmpExample');
   break;
}

parent(): Note that parent() is different than parents() in that it only selects the most immediate parent of the select element:

case 'tmpParent':
{
   $('li').parent('ul').addClass('tmpExample');
break;
}

children(): this method can be used to select specific children elements of a selected element, in this case all h4 tags in the tmpList div: 

case 'tmpChildren':
{
   $('div.tmpList').children('h4').addClass('tmpExample');
   break;
}

not(): The not() method allows to essentially deselect specific elements. In the case below, we want to select all list items, except those with the .tmpVegetables class: 

case 'tmpNot':
{
   $('ul li').not('li.tmpVegetables').addClass('tmpExample');
   break;
}


slice(): this method takes a beginning index value and ending index value as its parameters, allowing you to select a range of elements within a selection. 

case 'tmpSlice':
{
   $('ul#tmpAnimals li').slice(1, 4).addClass('tmpExample');
   break;
}


add(): The add() method allows to make a selection and then add elements to it, useful for constructing complicated selections of elements. Below we make a standard jQuery selection of all list items in the tmpAnimals unnumbered list, then we add the tmpBroccoli and tmpPepper list items.

case 'tmpAdd':
{
   $('ul#tmpAnimals li').add('li#tmpBroccoli, li#tmpPepper').addClass('tmpExample');
   break;
}


eq(): this method allows you to reduce a selection based on its index number. In the following example, we select all list items, which returns an array of all list items in the DOM. The then eq() method is chained to our selection and passed an index number of 10. Because indexes always start at 0, eq(10) selects the 11th list item in the DOM, i.e. "Buffalo": 

case 'tmpEq':
{
   $('ul li').eq(10).addClass('tmpExample');
   break;
}



Events in jQuery

Not surpisingly, event handlers in any programming language exist to deal with events: mouse clicks, mouse moves, drags, drops. In short, user interaction. Creating event handlers in oldschool JavaScript used to be really difficult, but jQuery makes it much easier. There are a few ways to deal with events in jQuery, but the bind() method is by far the easiest. 

The bind() method accepts two parameters: 

  1. the event name, such as ‘ready’, ‘mouseover’, ‘mouseout’, or ‘click’  
  2. a function call or anonymous function declaration (i.e. the entire body of the function is passed in as one lone parameter) 
Try the following example:

Example 5: the jQuery bind() method

[click here to see example 5 in action] [click here to download the Example 05 files]

 The bind() method simply attaches some other function or method to a particular event. In the case below, we have a very basic HTML5 document:

  1. <!doctype html>
  2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
  3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
  4. <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
  5. <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
  6. <meta charset="utf-8">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title>
  8. <meta name="description" content="">
  9. <meta name="author" content=""> <meta name="viewport" content="width=device-width">
  10. <link rel="stylesheet" href="css/style.css">
  11. <script src="/js/libs/modernizr-2.5.3.min.js"></script>
  12. </head>
  13. <body>
  14. <div></div>
  15. <div></div>
  16. <div></div>
  17. <div></div>
  18. <div></div>
  19. <div></div>
  20. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
  21. <script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js"><\/script>')</script>
  22. <script src="js/plugins.js"></script>
  23. <script src="js/script.js"></script>
  24. </body>
  25. </html>


And some simple CSS:

  1. @charset "UTF-8";
  2. /* CSS Document */
  3. div {
  4. border: 1px solid rgb(200, 200, 200);
  5. width: 100px;
  6. height: 100px;
  7. margin: 5px;
  8. float: left;
  9. }
  10. div.tmpExampleOver {
  11. background: #5092c5;
  12. }
  13. div.tmpExampleOn {
  14. background: #165b91;
  15. }


and the following  jQuery code in our script.js file:

  1. // JavaScript Document
  2. $(document).bind(
  3. 'ready',
  4. function() {
  5. $('div').bind(
  6. 'mouseover',
  7. function() {
  8. $(this).addClass('tmpExampleOver');
  9. }
  10. );
  11.  
  12. $('div').bind(
  13. 'mouseout',
  14. function() {
  15. $(this).removeClass('tmpExampleOver');
  16. }
  17. );
  18.  
  19. $('div').bind(
  20. 'click',
  21. function() {
  22. if ($(this).hasClass('tmpExampleOn')) {
  23. $(this).removeClass('tmpExampleOn');
  24. } else {
  25. $(this).addClass('tmpExampleOn');
  26. }
  27. }
  28. );
  29.  
  30. }
  31. );


The resulting index.html file, rendered in a browser, should look something like this:

example 05

[click screenshot to see the actual page in a browser]

As you can see, the six divs change background color as you hover the mouse over them (mouseover events), change back to their original background color when the mouse moves out (mouseout events) and toggles a dark blue background color when you click on any of them(click event). Let’s see how it works, shall we? 

Example 5: Explained

The HTML and CSS is fairly straightforward: six anonymous divs in the HTML, styled as six squares by the CSS. The CSS also has two additional classes: they add background colors for the mouseover state and the clicked state, respectively:

div.tmpExampleOver {
    background: #5092c5;
}

div.tmpExampleOn {
    background: #165b91;
}

 As per usual, the jQuery is where the interaction happens. The first thing that occurs is a use of the bind() method to attach further functions to the entire document when the ready event is detected:

$(document).bind( 'ready', ...)


The bind() method accepts two parameters: 1.)the event name, in this case ready and 2.) a function call or anonymous function declaration. We’ll be passing an entire anonymous function as one big parameter. The function we’re passing is really just three simple subroutines:

1.)To each div tag we’re binding a mouseover event function that adds the tmpExampleOver upon detecting any mouse over event:

    $('div').bind( 'mouseover',
        function() {
        $(this).addClass('tmpExampleOver');
      }
    );

2.)Then to each div we’ll bind an event that essentially undoes what we just did when the mouse leaves the div area: 

    $('div').bind(  'mouseout',
      function() {
        $(this).removeClass('tmpExampleOver');
      }
    );

And finally we’ll bind a click event to each div that adds tmpExampleOn class if it isn’t attached, and removes the class if it is attached: 

    $('div').bind(
      'click',
      function() {
        if ($(this).hasClass('tmpExampleOn')) {
          $(this).removeClass('tmpExampleOn');
        } else {
          $(this).addClass('tmpExampleOn');
        }
      }
    );


Advanced Event Handling 

As I said before, there a plenty of interesting ways to handle events in jQuery. The following example covers four of them:

Example 6: Advanced Event Handling Examples

[click here to play with this example in a browser] [click here to get the example code]

The HTML and CSS for this example is very similar to that of example 05 above, i.e. some anonymous divs styled to be 100px by 100px squares. The code found in the script.js file provides four different examples of the innovative and simple ways to deal with events. Each of these functions is declared when the document has loaded via this line of jQuery:

$(document).ready( function(){...});

Let’s examine each example. The first uses the standard bind() method we used in the previous example, but notice that it combines, or chains, three bind() methods together like so: $('div.tmpBind').bind(...).bind(...).bind(...); You may also notice that we’re using the find() method to find all children div tags within the div.tmpBind.

EXAMPLE 06.01:

  1. function() {
  2. //Example 06.01: handling events with the bind() method:
  3. $('div.tmpBind').bind(
  4. 'mouseover',
  5. function() {
  6. $(this).find('div').addClass('tmpExampleOver');
  7. }
  8. ).bind(
  9. 'mouseout',
  10. function() {
  11. $(this).find('div').removeClass('tmpExampleOver');
  12. }
  13. ).bind(
  14. 'click',
  15. function() {
  16. if ($(this).find('div').hasClass('tmpExampleOn')) {
  17. $(this).find('div').removeClass('tmpExampleOn');
  18. } else {
  19. $(this).find('div').addClass('tmpExampleOn');
  20. }
  21. }
  22. );
  23. //end of Example 01// JavaScript Document

Rather than bind(), Example 06.02 uses jQuery’s mouseover()mouseout(), and click() methods directly to add event functions, chaining them together like so:

$('div.tmpIndividual').mouseover(...).mouseout(...).click();

EXAMPLE 06.02:


  1. $('div.tmpIndividual').mouseover(
  2. function() {
  3. $(this).find('div').addClass('tmpExampleOver');
  4. }
  5. ).mouseout(
  6. function() {
  7. $(this).find('div').removeClass('tmpExampleOver');
  8. }
  9. ).click(
  10. function() {
  11. if ($(this).find('div').hasClass('tmpExampleOn')) {
  12. $(this).find('div').removeClass('tmpExampleOn');
  13. } else {
  14. $(this).find('div').addClass('tmpExampleOn');
  15. }
  16. }
  17. );
  18. //end of Example 02


Example 06.03 uses the very convenient jQuery hover() and toggle() methods.

The hover() methods takes two functions as parameters, following this pattern:

$(‘the_element’).hover( the function to be called when the mouse is moved over the_element,  the function to be called when the mouse is moved away from the_element);

The toggle() method is similar, except it deals with clicks rather than mouseover events:

$(‘the_element’).toggle(the function to be called when the mouse is clicked on the_element,  the function to be called when the mouse is clicked a again on the_element);

EXAMPLE 06.03:

  1. $('div.tmpPattern').hover(
  2. function() {
  3. $(this).find('div').addClass('tmpExampleOver');
  4. },
  5. function() {
  6. $(this).find('div').removeClass('tmpExampleOver');
  7. }
  8. ).toggle(
  9. function() {
  10. $(this).find('div').addClass('tmpExampleOn');
  11. },
  12. function() {
  13. $(this).find('div').removeClass('tmpExampleOn');
  14. }
  15. );


And finally Example 06.04, which uses JavaScript methods focus() and blur() to deal with what happens when a browser gives focus (or removes it) from different user interface elements. In this case, we have a simple <textarea> tag. Users can ‘focus’ on things like textareas or input boxes by using the tab key on their keyboard, or by clicking on them directly. ‘blur’ refers to what happens when the user tabs away or clicks somewhere else. Using the focus() and blur() methods, we can define event functions for precisely this type of user interaction:

EXAMPLE 06.04:

  1. $('div.tmpTrigger textarea').focus(
  2. function($e) {
  3. $(this).addClass('tmpFocused');
  4. }
  5. ).blur(
  6. function() {
  7. $(this).removeClass('tmpFocused');
  8. }
  9. );
  10. $('div.tmpTrigger textarea').focus();
  11. }

Above we are essentially adding the class .tmpFocused when a user focuses on the textarea in div#tmpTrigger, then removing that class when focus is removed, or blurred, as it is called. Also notice the last line in the function: 

$('div.tmpTrigger textarea').focus();


This forces browser focus on our textarea. Just calling the focus() method on a focussable element like <textarea> will give it immediate focus in the browser. (Note that with HTML5, this can be done without any JavaScript at all, as it is a built-in property of the new HTML5 form elements. However, it’s always nice to have fallbacks.) 

Putting our newfound jQuery knowledge to some good use

Ok, so we've learned a few important jQuery fundementals, and some interesting tricks. Now it is time to apply this knowledge to a project we've already worked on: The Farm at Richville site we recently converted to HTML5. Let's put a working slideshow into the site using a custom jQuery plugin we're going to write. 

[click here to take a look at the Farm at Richville site with working slideshow]

[click here to download the exercise files]

[click here to download the tutorial PDF

 

jQuery Animations


We already used prebuilt jQuery animtaion methods in the last exercise whehter we were aware of it or not. The  .fadeIn() and .fadeOut() methods we used for our slideshow are simple jQuery functions that increase or reduce respectively the CSS opacity property of an element. As we can see, these prebuilt methods are very useful.  But jQuery provides a very useful method for the custom animation of certain CSS properties. A proper implementation of the .animate() method will have the following structure:

$("#some_element").animate( {some_property:value; some_other_property:value;}[, duration] [, easing] [, call back function] );

You can pass any CSS properties with numeric values and animate() will all chnage them together from the selected element's original properties to the new values you choose.  [Click here] to download the following simple examples:

Example 01: Simple animation

This demo simply calls two .animate() methods: 

  1.  $("#clickhere").click(function() {
  2.    $("#animate1").animate({
  3.     height: "20px",
  4.     width: "10px",
  5.    }, 1000);
  6.    $("#animate2").animate({
  7.     height: "50px",
  8.     width: "500px"
  9.    }, 1000);
  10.  });

Example 02: Animating Multiple CSS Properties

[See the demo]. Any CSS property with a numeric value can be animated with jQuery. Font-size, border-width, margin, padding, top, left, bottom, and right can be animated simply by passing the desired end point to jQuery.animate(). These properties can be expressed either as %, px, or in ems:

  1.     $("#clickhere").click(function() {
  2.         $("#animate1").animate({
  3.             height: "20px",
  4.             width: "50%",
  5.             padding: "5em",
  6.             marginLeft: "40px",
  7.             borderWidth: "5px"
  8.         }, 1000);
  9.     });

 


Example 03: Animation Callback Functions

[See the demo]. The .animate() method can also accept a callback function, to be called when the animation has finished:

  1.     $("#clickhere").click(function() {
  2.         $("#animate1").animate({
  3.             height: "12px",
  4.             width: "50px"
  5.         }, 1000, function() {
  6.             alert('done!');
  7.         });
  8.     });

 


Example 04: Animation Chaining

[See the demo]. Like any other jQuery method, .animate() can be chained to other animations. Unless otherwise specified, each subsequent call to .animate() will fire only after the previous call in completed.  

  1.    $("#clickhere").click(function() {
  2.     $("#animate1").animate({
  3.      width: "200px"
  4.     }, 600).animate({