spacer
course logo
spacer page banner
active page logo

Week Four JavaScripting Notes

Example of a dropdown menu

<!DOCTYPE html>
<html>
<head>
<title>
  Dropdown Menuing
</title>
<style>
        .dropbtn {
        background-color: #3498DB;
          color: white;
          padding: 16px;
          font-size: 16px;
          border: none;
          cursor: pointer;
        }
        .dropbtn:hover, .dropbtn:focus {
          background-color: #2980B9;
        }
        .dropdown {
          position: relative;
          display: inline-block;
        }
        .dropdown-content {
          display: none;
          position: absolute;
          background-color: #f1f1f1;
          min-width: 160px;
          overflow: auto;
          box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
          z-index: 1;
        }
        .dropdown-content a {
          color: black;
          padding: 12px 16px;
          text-decoration: none;
          display: block;
        }
        .dropdown a:hover {background-color: #ddd;}
        .show {display: block;}
    </style>
    </head>
    <body>
        <h2>Clickable Dropdown</h2>
        <p>Click on the button to open the dropdown menu.</p>
       <div class="dropdown">
          <button onclick="myFunction()" class="dropbtn">Dropdown</button>
          <div id="myDropdown" class="dropdown-content">
            <a href="#home">Home</a>
            <a href="#about">About</a>
            <a href="#contact">Contact</a>
          </div>
        </div>
<script>
/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */

function myFunction() {
  document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
  if (!event.target.matches('.dropbtn')) {
    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i=0; i<dropdowns.length; i++) {
        var openDropdown = dropdowns[i];
        if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
        }
    }
  }
}
</script>
</body>

Rollovers

Let's look at rollovers and windowing techniques in order to gain some insight into their evolution.

Introduction to Rollovers

Popular first-generation JavaScript Rollovers are well presented by Joe Maller on the Web.

The <SCRIPT LANGUAGE="JavaScript"></SCRIPT> tag set separate a rollover script from the rest of the document. It's typical to enclose the entire content of the script tagset in an HTML comment if you are worried about accidentally displaying script code as text on older browsers.

Remember that comments in JavaScript can consist of the /* */ sequence anywhere within a script or consist two forward slashes // to indicate that all text that follows on the same line is ignored in processing the script. Comments are a good place to put any notes you would want to have should you inherit code from someone else.

Declaring Images in the Script

The first step in creating a rollover is to declare to your JavaScript the images the rollover will use. Declaring the images causes the JavaScript interpreter to load the images into browser memory before they become visible. Once the images are cached, the image swaps can happen instantaneously.

It is possible to use a rollover technique without declaring and preloading the images, but before an image changes the browser must first open a new connection, download the image, and load for viewing. This connection-download-load process takes long enough, even on fast connections, to make the rollover less effective than when you preload every image.

To preload the images efficiently, you can declare each with two lines of code in conjunction with an array. Arrays are like mini files in computer memory, storing several pieces of information in one sequential place for efficient access via a common labeled name for the array's components. Our array, named Rollimage, will store each image name, location, and bounds (the x and y dimension of the raster image):

Rollimage = new Array();
   
Rollimage[0] = new Image(100,150); 
Rollimage[0].src = "your_image.gif"; 

Rollimage[1] = new Image(100,150);
Rollimage[1].src = "your_other_image.gif";

The first line above initializes the array, and following numbered sets of lines are the declaration of each additional image. The first line of each set declares the image's size and the second assigns its address. The numbers inside the parentheses refer to the width and height of the image, in that order. A non-local image would need to have its full path presented within a well-formed URL in the second line of the code. The src property of an HTML IMG element holds the source of an image to be presented in a Web browser.

Early versions of JavaScript were case sensitive. More recent version claim to be partly case sensitive but the boundaries of when case matters and when it doesn't are unclear. To be on the safe side, be sure to refer to your variables and arrays with consideration of case. Rollimage is different than rollimage.

Naming Image Objects

To replace an image upon rolling over it's visual bounds, you need to give your JavaScript a way to identify which image to replace in each instance. Do this by including a name attribute in the <IMG> tag or learning to refer to images by using JavaScript's Array syntax:

document.images[2]

By default, a Web browser counts every image on a page and refers to them numerically starting from the first image encountered sequentially in the code. The above refers to the third image tag the browser encounters when loading the HTML document. Consider that the browser conventionally counts starting with zero as the first item in memory is offset by zero objects from the location of the Array's label address.

I've found named images easier to keep track of so that's what I use in this example. The following image is named "Rupert":

<IMG NAME="Rupert" SRC="some.gif">

Rollovers are often used to provide visual feedback during link selection on a menu. As a result, the rollover images typically nest inside open and closing anchor (A) tags:

<A HREF="link.html"
  onMouseOver="SwapOut()"
  onMouseOut="SwapBack()">
<IMG NAME="Rupert" SRC="your_image.gif" WIDTH="100" HEIGHT="150">
</A>

What's "onMouseOver"?

onMouseOver and onMouseOut are event handlers that tell JavaScript what to do when an event occurs. The mouse cursor passing over the linked image's bounds is defined as an event because of these bits of code. onMouseOver="blorg()" would tell JavaScript to execute the function blorg().

Functions

Functions are a predefined set of commands that JavaScript only executes when called. To be ready for use at the necessary time, they are usually defined in the first <SCRIPT> section of the document. The standard format for defining a function is:
function SwapOut() {
  document.Rupert.src = Rollimage[1].src;
  return true;
} 

That function's name is SwapOut(). The parentheses can be used in more complex scripts to send data that the function will work with. The guts of the function are written between the {} brackets.

SwapOut() tells the Rupert image's src attribute to equal Rollimage[1].src, which is the second image from the array created earlier. In English, it changes the source of the Rupert image. The other function in this document, SwapBack(), is almost the same as SwapOut() except that it switches back to the first image in the array:

function SwapBack(){
  document.Rupert.src = Rollimage[0].src;
  return true;
}

Putting It All Together

That's basically it. Following is the complete code for a simple document with one rollover image. Try it out:

<HTML>
<HEAD>
<TITLE>
  JavaScript Rollover by Joe Maller
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  <!-- hide from non JavaScript Browsers
  Rollimage = new Array()
  Rollimage[0]= new Image(121,153)
  Rollimage[0].src = "http://bdcampbell.net/javascript/joe_open.jpg"
  Rollimage[1] = new Image(121,153)
  Rollimage[1].src = "http://bdcampbell.net/javascript/joe_blink.jpg"
  Rollimage[2] = new Image(121,153)
  Rollimage[2].src = "http://bdcampbell.net/javascript/joe_tongue.jpg"
  
  function SwapBack(){
    document.joe_image.src = Rollimage[0].src; 
    return true;
  }
  function SwapOut(){
    document.joe_image.src = Rollimage[1].src;
    return true;
  }
  function TongueOut(){
    document.joe_image.src = Rollimage[2].src; 
    return true;
  }
  // - stop hiding --> 
</script>
</head>
<body bgcolor="#FFFFFF">
<center> 
<div><img src="http://bdcampbell.net/javascript/joe_open.jpg"
  name="joe_image" 
  width=121
  height=153
  border=0
  onmouseover="SwapOut()"
  onmouseout="SwapBack()"
  onclick="TongueOut()" /></div> 
</center>

<P align="center"> 
  If you use this, please give Joe credit.
</P>
</BODY>
</HTML>

Notes on JavaScript rollovers:

  • Quotation marks
    Misplaced quote marks cause unbelievable problems. Make sure that single and double quote marks are properly nested and closed. The same goes for parentheses and curly braces.

  • Naming
    When changing names of objects, be sure to change every instance of that name everywhere in script and each named object on the page. No two objects should have the same name.

  • LOWSRC
    If you use a Low Source in your image tags, you might experience unwanted reloads of the LOWSRC image before every swap.

  • Image Size — The size of the image is set by the image you will be replacing. Replacement images will be stretched to fit. Setting the image size in the array seems to be optional, images will stretch to fit the size specified in the <IMG> tag. If the images are different sizes and the <IMG> tag does not specify height and width, the rollover will act unpredictably, possibly using the images at their actual saved size.

CSS based rollovers

Compare the JavaScript technique of creating a rollover with the CSS technique whereby we change the style of a Web page component via cascading style sheet features than via swapping images:

Here is the HTML used to create this rollover. You may notice that it is much shorter, and easier to remember than a JavaScript rollover. Essentially, you just need to define a class and everything else is handled with CSS

<center>
<div class="rollover" style="width:120px; height:152px"></div>
</center>

The Style Sheet

The key to making this work in all modern browsers is to define your links as block elements in your style sheet ( display: block ), and making the width the same as your image’s ( eg. width: 32px ). Choose a background colour for your link that matches your page background and a second colour that you want for the rollover effect ( defined in a:hover ). For example:

<style type="text/css">
<!--
.rollover { display:block; background-image: url("http://bdcampbell.net/javascript/joe_open.jpg")} .rollover:hover { background-image: url("http://bdcampbell.net/javascript/joe_blink.jpg")}
-->
</style>

This will create one rollover image per line. You can then use nested <div> tags, tables, and/or CSS positioning to better control the placement of these rollovers on your page. For a working example, take a look at the left-hand navigation on this site.

Why would you use CSS instead of Javascript?

  • Less code for you to write and debug
  • 50% fewer image files to create / update
  • 50% fewer images to download saves bandwidth
  • Changing the text and rollover colors is fast and easy.

Try an on-line rollover automation tool output example

There are many JavaScript automation tools available on-line. Once you've learned JavaScript, you'll be able to look behind the scenes to see how the JavaScript works and reverse engineer how each tool works (should you be interested). Here's the result of my use of a simple tool that created a simple, two item menu (the tool no longer exists online):
 

which generates the following code:

<style type="text/css">
.menu {font-family:Centaur; font-size:12pt; font-weight:bold; color:#000000}
</style>
<script language="javascript">
function movein(which,html) {
document.getElementById(which).style.background='#009900';
document.getElementById("description").innerHTML=html;
}

function moveout(which) {
document.getElementById(which).style.background='#99FF00';
document.getElementById("description").innerHTML=' ';
} </script>
<!-- Place code above between your head tags-->
<!-- Place code below between your body tags-->
<table bgcolor="black" border="1" cellpadding="2" cellspacing="0" width="150"><tr>
<td class="menu" bordercolor="black" id="choice1" style="cursor:hand;background-color:#99FF00" onMouseOver="movein('choice1','Connecting 3-D Cyberspace')" onMouseOut="moveout('choice1')" onClick="location.href='http://www.oworld.org/'">
<div align="center">OWorld</div>
</td>
</tr>
<td class="menu" bordercolor="black" id="choice2" style="cursor:hand;background-color:#99FF00" onMouseOver="movein('choice2','Center for Environmental Visualization')" onMouseOut="moveout('choice2')" onClick="location.href='http://www.cev.washington.edu/'">
<div align="center">CEV</div>
</td>
</tr>

<tr>
<td bordercolor="black" bgcolor="white" height="18"><font id="description" face="arial" size="1"></font></td>
</tr>
</table>

JQuery Rollovers

There are many rollover techniques to try with JQuery. We'll take a look at the code behind just one of seventeen time-tested examples you can admire.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Rollover Fade Method</title>
<style type="text/css" media="screen">
<!--
BODY { margin: 10px; padding: 0; font: 1em "Trebuchet MS", verdana, arial, sans-serif; font-size: 100%; }
H1 { margin-bottom: 2px; }
-->
</style>
  
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript">
  <!--
    
    // wrap as a jQuery plugin and pass jQuery in to our anonymous function
    (function ($) {
           $.fn.cross = function (options) {
               return this.each(function (i) { 
                   // cache the copy of jQuery(this) - the start image
                   var $$ = $(this);
  
                   // get the target from the backgroundImage + regexp
                   var target = $$.css('backgroundImage').replace(/^url|[\(\)'"]/g, '');

// nice long chain: wrap img element in span $$.wrap('<span style="position: relative;"></span>') // change selector to parent - i.e. newly created span .parent() // prepend a new image inside the span .prepend('<img>') // change the selector to the newly created image .find(':first-child') // set the image to the target .attr('src', target); // the CSS styling of the start image needs to be handled differently for different browsers if ($.browser.msie || $.browser.mozilla) { $$.css({ 'position' : 'absolute', 'left' : 0, 'background' : '', 'top' : this.offsetTop }); } else if ($.browser.opera && $.browser.version < 9.5) { $$.css({ 'position' : 'absolute', 'left' : 0, 'background' : '', 'top' : "0" }); } else { // Safari $$.css({ 'position' : 'absolute', 'left' : 0, 'background' : '' }); } // similar effect as single image technique, except using .animate // which will handle the fading up from the right opacity for us $$.hover(function () { $$.stop().animate({ opacity: 0 }, 250); }, function () { $$.stop().animate({ opacity: 1 }, 250); }); }); }; })(jQuery); // note that this uses the .bind('load') on the window object, rather than $(document).ready() // because .ready() fires before the images have loaded, but we need to fire *after* because // our code relies on the dimensions of the images already in place. $(window).bind('load', function () { $('img.fade').cross(); }); //--> </script> </head> <body> <h1>Fade Method - Single Image Technique</h1> <p>This technique uses jQuery to modify the markup and to animate to fade transition.</p> <p><a href="http://jqueryfordesigners.com/image-cross-fade-transition/">Read the article, and see the screencast this demonstration relates to</a></p> <div> <img class="fade" src="images/who.jpg" style="background: url(images/who_ro.jpg);" alt="Who we are" /> <img class="fade" src="images/who.jpg" style="background: url(images/who_ro.jpg);" alt="Who we are" /> <img class="fade" src="images/who.jpg" style="background: url(images/who_ro.jpg);" alt="Who we are" /> </div> <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-1656750-8"; urchinTracker(); </script> </body> </html>

JavaScript Window Popups with the window.open Function

Take a look at the following simple primer from tizag.com.

The window.open() function creates a new browser window, customized to your specifications, without the use of an HTML anchor tag. In this example, we will be making a function that utilizes the window.open() function.

HTML & JavaScript Code:

<head>
<script type="text/javascript">
<!--
function myPopup() {
window.open( "http://www.google.com/" )
}
//-->
</script>
</head>

<body>
<form>
<input type="button" onClick="myPopup()" value="POP!">
</form>
<p onClick="myPopup()">CLICK ME TOO!</p>
</body>

Display:

CLICK ME TOO!

This works with pretty much any tag that can be clicked on, so please go ahead and experiment with this fun little tool. Afterwards, read on to learn more about the different ways you can customize the JavaScript window that pops up.

JavaScript Window.Open Arguments

There are three arguments that the window.open function takes:

  1. The relative or absolute URL of the webpage to be opened.
  2. The text name for the window.
  3. A long string that contains all the different properties of the window.

Naming a window is very useful if you want to manipulate it later with JavaScript. However, this is beyond the scope of this lesson, and we will instead be focusing on the different properties you can set with your brand spanking new JavaScript window. Below are some of the more important properties:

  • dependent - Subwindow closes if the parent window (the window that opened it) closes
  • fullscreen - Display browser in fullscreen mode
  • height - The height of the new window, in pixels
  • width - The width of the new window, in pixels
  • left - Pixel offset from the left side of the screen
  • top - Pixel offset from the top of the screen
  • resizable - Allow the user to resize the window or prevent the user from resizing, currently broken in Firefox.
  • status - Display or don't display the status bar

Dependent, fullscreen, resizable, and status are all examples of ON/OFF properties. You can either set them equal to zero to turn them off, or set them to one to turn them ON. There is no inbetween setting for these types of properties.

Upgraded JavaScript Popup Window!

Now that we have the tools, let's make a sophisticated JavaScript popup window that we can be proud of!

HTML & JavaScript Code:

<head>
<script type="text/javascript">

<!--
function myPopup2() {
window.open( "http://www.google.com/", "myWindow", 
"status = 1, height = 300, width = 300, resizable = 0" )
}
//-->
</script>
</head>
<body>
<form>
<input type="button" onClick="myPopup2()" value="POP2!">
</form>

<p onClick="myPopup2()">CLICK ME TOO!</p>
</body>

Display:

CLICK ME TOO!

Now, that is a prime example of a worthless popup! When you make your own, try to have them relate to your content, like a small popup with no navigation that just gives the definition or explanation of a word, sentence, or picture!

Expanded Tooltips

If you want to show additional information in a new layer but not have to generate a new window, you can expand on the tooltip concept like this framework here.

Basically, you can add new content to a page through an event handler. Let's look at a function that adds content via the document.getElementById() function and the innerHTML property available in JavaScript.

Take a look at the code:

<script>
function showme() {
   var txt=document.getElementById("popup");
   txt.innerHTML="<img src=yinyang.png>";
}

function removeme() {
   var txt=document.getElementById("popup");
   txt.innerHTML="";
}
</script>

which works with an existing DIV element:

<div id="popup" style="position:relative;top:0px;left:700px;height:182px;width:169px;z-index:5"></div>

JQuery windowing

Let's try an example of internal page popups with JQuery. The code is here:
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Draggable - Default functionality</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <style type="text/css">
  body
  {
  	font-family:Verdana, Arial, Helvetica, sans-serif;
  	font-size:11px
  }
  #layer1
  {
  	position: absolute;
  	left:200px;
  	top:100px;
  	width:250px;
  	background-color:#f0f5FF;
  	border: 1px solid #000;
  	z-index: 50;
  	visibility: hidden;
  	cursor: pointer;
  }
  #layer1_handle
  {
  	background-color:#5588bb;
  	padding:2px;
  	text-align:center;
  	font-weight:bold;
  	color: #FFFFFF;
  	vertical-align:middle;
  }
  #layer1_content
  {
  	padding:5px;
  }
  #close
  {
  	float:right;
  	text-decoration:none;
  	color:#FFFFFF;
  }
  h1, h2
  {
  	font-size:20px;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
  $( function() {
    $("#layer1").draggable();
    $("#preferences").click(function() {
    	$("#layer1").css("visibility", "visible");
	});
	$("#close").click(function() {
    	$("#layer1").css("visibility", "hidden");
    });
  } );
  </script>
</head>
<body>
<h2>JQuery Tutorial Demo: Floating Dialog Windows</h2>
<p>Here is the demo on using floating dialog windows by using the form and interface plug-in of jQuery</p>

<div id="content"><input type="button" id="preferences" value="Edit Preferences" /></div>
<div id="layer1">
    <div id="layer1_handle">
    <a href="#" id="close">[ x ]</a>
    Preferences
    </div>
    <div id="layer1_content">
        <form id="layer1_form" method="post" action="save_settings.php">
        Display Settings<br />
        <input type="radio" name="display" checked="checked" value="Default" />Default<br />
        <input type="radio" name="display" value="Option A" />Option A<br />
        <input type="radio" name="display" value="Option B" />Option B<br /><br />
        Autosave settings<br />
        <input type="radio" name="autosave" checked="checked" value="Enabled" />Enabled<br />
        <input type="radio" name="autosave" value="Disabled" />Disabled<br /><br />
        <input type="submit" name="submit" value="Save" />
        </form>
    </div>
</div>
</body>
</html>

Workbook Available for Skills Practice

The relevant workbook is here for you to practice skills with the ideas presented in this document.