Watch our 3-minute video to find out how you can learn JavaScript with a live instructor.
Additional Resources

Dynamic HTML

In this lesson of the JavaScript tutorial, you will learn...
  1. To change the values of CSS properties dynamically.
  2. To hide and show elements.
  3. To dynamically modify the content fo elements.
  4. To manipulate tables dynamically.
  5. To position elements dynamically.
  6. To change the z-index order of elements.

Introduction

Dynamic HTML is not a technology in and of itself, but rather is a combination of three technologies: HTML, Cascading Style Sheets (CSS), and JavaScript. It usually involves using JavaScript to change a CSS property of an HTML element. In modern browsers, most CSS properties can be modified dynamically. This can be done by changing an individual style of element (using the style property of the element) or by changing the class name assigned to the element (using the className property).

Accessing and Modifying Styles

The style object is a collection of an element's styles that are either defined within that HTML element's style attribute or directly in JavaScript. Styles defined in the <style> tag or in an external style sheet are not part of the style object. The W3C specifies a method for getting at the current (or actual) style of an object: the window object's getComputedStyle() method, which is supported by the latest versions of Mozilla, but not by Internet Explorer 6 and earlier. Internet Explorer provides a non-standard property for getting at the current style of an element: the currentStyle property.

Standard Syntax

window.getComputedStyle(Element, Pseudo-Element)

//for example:
var curStyle = window.getComputedStyle(
  document.getElementById("divTitle"), null);
alert(curStyle.fontWeight);

Internet Explorer Syntax

Element.currentStyle.Property
//for example:
alert(document.getElementById("divTitle").currentStyle.fontWeight);

Cross-browser Solution

var curStyle;
if (window.getComputedStyle) {
 curStyle = window.getComputedStyle(
  document.getElementById("divTitle"), "");
} else {
 curStyle = document.getElementById("divTitle").currentStyle;
}
alert(curStyle.fontWeight);

Another solution is to use JavaScript to set the styles of the objects on the page.

function init(){
 document.getElementById("divTitle").style.fontWeight = "bold";
}

Now this style can be referenced later in the script; however, this solution isn't always practical.

Hiding and Showing Elements

Elements can be hidden and shown by changing their visibility or display values. The visibility style can be set to visible or hidden and the display property can be set to block, table-row, none, and several other values. The two work slightly differently as the following example illustrates.

Code Sample: DynamicHtml/Demos/Visibility.html

<html>
<head>
<title>Showing and Hiding Elements with JavaScript</title>
<script type="text/javascript" src="EnvVars.js"></script>
<script type="text/javascript">

function changeVisibility(TR){
 if (document.getElementById(TR).style.visibility=="hidden") {
  document.getElementById(TR).style.visibility = "visible";
 } else {
  document.getElementById(TR).style.visibility = "hidden";
 }
}

var TR_DISPLAY = (IS_IE) ? "block" : "table-row";

function changeDisplay(TR){
 if (document.getElementById(TR).style.display == "none") {
  document.getElementById(TR).style.display = TR_DISPLAY;
 } else {
  document.getElementById(TR).style.display = "none";
 }
}
</script>
</head>
<body>
<h1>Hiding and Showing Elements</h1>
<table border="1">
 <tr id="tr1"><td>tableElem Row 1</td></tr>
 <tr id="tr2"><td>tableElem Row 2</td></tr>
 <tr id="tr3"><td>tableElem Row 3</td></tr>
 <tr id="tr4"><td>tableElem Row 4</td></tr>
</table>
<form>
 <h2>visibility</h2>
 <input type="button" onclick="changeVisibility('tr1')" value="TR1">
 <input type="button" onclick="changeVisibility('tr2')" value="TR2">
 <input type="button" onclick="changeVisibility('tr3')" value="TR3">
 <input type="button" onclick="changeVisibility('tr4')" value="TR4">
 
 <h2>display</h2>
 <input type="button" onclick="changeDisplay('tr1')" value="TR1">
 <input type="button" onclick="changeDisplay('tr2')" value="TR2">
 <input type="button" onclick="changeDisplay('tr3')" value="TR3">
 <input type="button" onclick="changeDisplay('tr4')" value="TR4">
</form>
</body>
</html>
Code Explanation

This page has two functions: changeVisibility() and changeDisplay(). The changeVisibility() function checks the value of the visibility style of the passed element and changes it to its opposite. The changeDisplay() function does the same with the display style. The functions are called with buttons on the page and are passed in ids of table rows from the table on the page.

The main difference between setting visibility to hidden and setting display to none is that setting visibility to hidden does not modify the layout of the page; it simply hides the element. Setting display to none, on the other hand, collapses the element, so that the surrounding relatively positioned elements re-position themselves.

In the screenshot below, tableElem Row 1 has visibility set to hidden and tableElem Row 3 has display set to none.

The following line of code may have grabbed your attention:

var TR_DISPLAY = (IS_IE
							
						) ? "block" : "table-row";

According to the CSS specification, the proper way to display a table row is by setting the display property to table-row; however Internet Explorer 6 and earlier do not support this value. To get the script to behave correctly in IE6, the display must be set to block; however, that messes up Mozilla, which displays blocks as blocks, not as table rows. The solution is to create a variable, TR_DISPLAY, whose value depends on the browser being used. That's exactly what the line of code above does.

Exercise: Showing and Hiding Elements

Duration: 20 to 30 minutes.

In this exercise, you will modify a Math Quiz to only show the countdown timer when it is running.

  1. Open DynamicHtml/Exercises/MathQuiz.html for editing.
  2. Modify the code so that the table row with the timer in it (the last row) only shows up when the timer is running. Note that the variable TR_DISPLAY is already set to the proper browser-dependent value. Hint: You will make your changes in resetTimer() and decrementTimer().
  3. Test your solution in a browser.

Only show the Answer row when a question is selected.

The innerHTML Property

Internet Explorer 4+ and the latest Mozilla browsers (Netscape 6+ and Firefox) support the non-standard innerHTML property of an element. The innerHTML property can be used to read and set the HTML content of an element. The following example illustrates this.

Code Sample: DynamicHtml/Demos/innerHTML.html

<html>
<head>
<title>innerHTML</title>
</head>
<body>
<div id="divGreeting">
 <h1>Hello!</h1>
</div>
<form>
 <input type="button" value="Return Greeting"
  onclick="document.getElementById('divGreetingBack').innerHTML =
   document.getElementById('divGreeting').innerHTML;">
</form>
<div id="divGreetingBack"></div>
</body>
</html>
Code Explanation

When the user clicks the "Return Greeting" button, the HTML content of divGreeting is copied into divGreetingBack.

Exercise: Using innerHTML for Cleaner Messages

Duration: 10 to 20 minutes.

In this exercise, you will modify the Math Quiz so that it displays messages in plain text, rather than in form fields and alerts.

  1. Open DynamicHtml/Exercises/MathQuizInnerHTML.html for editing.
  2. Replace the TimeLeft text field with a span with an id of "spanTimeLeft".
  3. Beneath the form, add an empty div with the id of "divMessage".
  4. Create a new function called showMessage(), which takes to arguments: the message to show and the color to display it in. This function should do the following:
    • Set the innerHTML property of divMessage to the passed-in message.
    • Change the value of the color style of divMessage to the passed-in color.
    • Display divMessage as a block.
  5. Replace the two alerts in checkAnswer() with calls to showMessage(). Pass in green as the color if the answer is correct and red if it is not.
  6. You may find it useful to look at the decrementTimer() function, which already has some modifications.

Code Sample: DynamicHtml/Exercises/MathQuizInnerHTML.html

---- Code Omitted ----
function decrementTimer(){ TIMES_UP = false; document.getElementById("trTimer").style.display = TR_DISPLAY; document.getElementById("divMessage").innerHTML = ""; document.getElementById("divMessage").style.display = "none"; document.getElementById("spanTimeLeft").innerHTML=TIME_LEFT + " "; document.getElementById("trTimer").style.visibility = "visible"; INTERVAL--; if (TIME_LEFT >= 0) { TIMER = setTimeout(decrementTimer, 1000); } else { showMessage("Time's up! The answer is " + getAnswer() + ".", "red"); resetTimer(INTERVAL); } }
---- Code Omitted ----

Manipulating Tables

HTML tables can be created and manipulated dynamically with JavaScript. Each table element contains a rows array and methods for inserting and deleting rows: insertRow() and deleteRow(). Each tr element contains a cells array and methods for inserting and deleting cells: insertCell() and deleteCell(). The following example shows how these objects can be used to dynamically create HTML tables.

Code Sample: DynamicHtml/Demos/table.html

<html>
<head>
<title>Manipulating Tables</title>
<script type="text/javascript">
function addRow(tableId, cells){
 var tableElem = document.getElementById(tableId);
 var newRow = tableElem.insertRow(tableElem.rows.length);
 var newCell;
 for (var i = 0; i < cells.length; i++) {
  newCell = newRow.insertCell(newRow.cells.length);
  newCell.innerHTML = cells[i];
 }
 return newRow;
}

function deleteRow(tableId, rowNumber){
 var tableElem = document.getElementById(tableId);
 if (rowNumber > 0 && rowNumber < tableElem.rows.length) {
  tableElem.deleteRow(rowNumber);
 } else {
  alert("Failed");
 }
}
</script>
</head>

<body>
<table id="tblPeople" border="1">
<tr>
 <th>First Name</th>
 <th>Last Name</th>
</tr>
</table>
<hr>
<form name="formName">
 First Name: <input type="text" name="FirstName"><br>
 Last Name: <input type="text" name="LastName"><br>
 <input type="button" value="Add Name"
  onclick="addRow('tblPeople',
   [this.form.FirstName.value, this.form.LastName.value] );">
 <hr>
 Remove Row: <input type="text" size="1" name="RowNum">
 <input type="button" value="Delete Row"
  onclick="deleteRow('tblPeople', this.form.RowNum.value)">
</form>
</body>
</html>
Code Explanation

The body of the page contains a table with an id of formName. The table contains a single row of headers.

<table id="tblPeople" border="1">
<tr>
 <th>First Name</th>
 <th>Last Name</th>
</tr>
</table>

Below the table is a form that allows the user to enter a first and last name. When the "Add Name" button is clicked, the addRow() function is called and passed in the id of the table (tblPeople) and a new array containing the user-entered values.

First Name: <input type="text" name="FirstName"><br>
Last Name: <input type="text" name="LastName"><br>
<input type="button" value="Add Name"
 onclick="addRow('tblPeople',
 [this.form.FirstName.value, this.form.LastName.value] );">

The addRow() function uses the insertRow() method of the table to add a new row at the end of the table and then loops through the passed-in array, creating and populating one cell for each item. The function also returns the new row. Although the returned value isn't used in this example, it can be useful if you then want to manipulate the new row further.

function addRow(tableId, cells){
 var tableElem = document.getElementById(tableId);
 var newRow = tableElem.insertRow(tableElem.rows.length);
 var newCell;
 for (var i = 0; i < cells.length; i++) {
  newCell = newRow.insertCell(newRow.cells.length);
  newCell.innerHTML = cells[i];
 }
 return newRow;
}

The form also contains a "Delete Row" button that, when clicked, passes the id of the table (tblPeople) and the number entered by the user in the RowNum text field.

Remove Row: <input type="text" size="1" name="RowNum">
<input type="button" value="Delete Row"
 onclick="deleteRow('tblPeople', this.form.RowNum.value)">

The deleteRow() function checks to see if the row specified exists and is not the first row (the header row). If both conditions are true, it deletes the row. Otherwise, it alerts "Failed".

function deleteRow(tableId, rowNumber){
 var tableElem = document.getElementById(tableId);
 if (rowNumber > 0 && rowNumber < tableElem.rows.length) {
  tableElem.deleteRow(rowNumber);
 } else {
  alert("Failed");
 }
}

Exercise: Tracking Results in the Math Quiz

Duration: 15 to 25 minutes.

In this exercise, you will dynamically create a table that shows the user how she is doing on the Math Quiz. The screenshot below shows how the result will look.

  1. Open DynamicHtml/Exercises/MathQuizTable.html for editing.
  2. Notice that the addRow() function is included and that there is an additional function called getQuestion(), which returns the question that is currently selected.
  3. Also notice that there is a table at the bottom of the body of the page with an id of tblResults.
  4. Modify the checkAnswer() function so that it does the following:
    • Creates an array to hold the current question and answer.
    • Adds a new row to the tblResults table.
  5. Test your solution in a browser.

Modify the code so that the new row's font color is green if the answer is correct and red if it is not. Hint: the addRow() function returns the newly added row.

Dynamically Changing Dimensions

The dimensions of an object can be changed by modifying the width and height properties of the element's style property. The following example demonstrates this.

Code Sample: DynamicHtml/Demos/Dimensions.html

<html>
<head>
<title>Dimensions</title>
<style type="text/css">
#divBlock {
 height:100px;
 width:100px;
 background-color:red;
}
</style>
<script type="text/javascript">
function init(){
 document.getElementById("divBlock").style.width = "100px";
 document.getElementById("divBlock").style.height = "100px";
}

function grow(elem){
 var objElem = elem;
 var curWidth = parseInt(objElem.style.width);
 var curHeight = parseInt(objElem.style.height);
 objElem.style.width = (curWidth * 1.5) + 'px';
 objElem.style.height = (curHeight * 1.5) + 'px';
}

function shrink(elem){
 var objElem = elem;
 var curWidth = parseInt(objElem.style.width);
 var curHeight = parseInt(objElem.style.height);
 objElem.style.width = (curWidth / 1.5) + 'px';
 objElem.style.height = (curHeight / 1.5) + 'px';
}
</script>
</head>
<body onload="init();">
<div id="divBlock" onmouseover="grow(this);" 
  onmouseout="shrink(this);"></div>
</body>
</html>
Code Explanation

In this case, we use the init() function to set the height and width of the divBlock div, thus making the properties accessible to JavaScript.

The grow() function uses parseInt() to cut off the units (e.g, px) from the value of the width and height of the div and assign the resulting integers to variables: curWidth and curHeight. It then modifies the width and height properties of the element by multiplying the current values by 1.5.

The shrink() function does the same thing, but it divides by 1.5 instead of multiplying.

The functions are triggered with onmouseover and onmouseout event handlers.

Creating a Timed Slider

The example below shows how a timed slider can be created by dynamically changing an element's dimensions.

Code Sample: DynamicHtml/Demos/Slider.html

<html>
<head>
<title>Slider</title>
<style type="text/css">
#divSlider {
 height:10px;
 width:0px;
 background-color:red;
 position:relative;
 top:-11px;
 left:1px;
}

#divSliderBG {
 height:12px;
 width:102px;
 background-color:blue;
}
</style>
<script type="text/javascript">

var TIMER, TIMES_UP, Slider;
function resetTimer(){
 TIMES_UP = true;
 var slider = document.getElementById("divSlider");
 slider.style.width = "0px";
 clearTimeout(TIMER);
}

function decrementTimer(){
 TIMES_UP = false;
 var slider = document.getElementById("divSlider");
 var curWidth = parseInt(slider.style.width);
 if (curWidth < 100) {
  slider.style.width = curWidth + 1 + "px";
  TIMER = setTimeout(decrementTimer, 100);
 } else {
  alert("Time's up!");
  resetTimer();
 }
}
</script>
</head>

<body onload="resetTimer();">

<div id="divSliderBG"><img src="Images/Transparent.gif" 
  height="1" width="1"></div>
<div id="divSlider"><img src="Images/Transparent.gif" 
  height="1" width="1"></div>

<form>
 <input type="button" value="Start Timer" onclick="decrementTimer();">
</form>

</body>
</html>

Positioning Elements Dynamically

The position of an object can be changed by modifying the left and top properties of the element's style property. The following example demonstrates this.

Code Sample: DynamicHtml/Demos/Position.html

<html>
<head>
<title>Position</title>
<style type="text/css">
#divBlock {
 position:relative;
 height:100px;
 width:100px;
 top:100px;
 left:100px;
 background-color:red;
}
</style>
<script type="text/javascript">
function init(){
 document.getElementById("divBlock").style.top = "100px";
 document.getElementById("divBlock").style.left = "100px";
}

function moveH(elem, distance){
 var objElem = document.getElementById(elem);
 var curLeft = parseInt(objElem.style.left);
 objElem.style.left = (curLeft + distance) + "px";
}

function moveV(elem, distance){
 var objElem = document.getElementById(elem);
 var curTop = parseInt(objElem.style.top);
 objElem.style.top = (curTop + distance) + "px";
}
</script>
</head>
<body onload="init();">
<form>
<input type="button" value="Left" onclick="moveH('divBlock',-10);">
<input type="button" value="Right" onclick="moveH('divBlock',10);">
<input type="button" value="Up" onclick="moveV('divBlock',-10);">
<input type="button" value="Down" onclick="moveV('divBlock',10);">
</form>
<div id="divBlock"></div>
</body>
</html>
Code Explanation

We again use the init() function, this time to set the top and left properties of the divBlock div, thus making the properties accessible to JavaScript.

The moveH() function uses parseInt() to cut off the units (e.g, px) from the value of the left property of the div and assign the resulting integer to the curLeft variable. It then modifies the left property of the element by adding the value passed in for distance.

The moveV() function does the same thing, but it modifies the top property rather than the left property.

The functions are triggered with onclick event handlers.

Creating a Different Timed Slider

The example below shows how a different type of timed slider can be created by dynamically changing an element's position.

Code Sample: DynamicHtml/Demos/Slider2.html

<html>
<head>
<title>Slider</title>
<style type="text/css">
#divSlider {
 height:10px;
 width:2px;
 background-color:red;
 position:relative;
 top:-11px;
 left:1px;
}

#divSliderBG {
 height:12px;
 width:102px;
 background-color:blue;
}
</style>
<script type="text/javascript">

var TIMER, TIMES_UP, Slider;
function resetTimer(){
 TIMES_UP = true;
 var slider = document.getElementById("divSlider");
 slider.style.left = "1px";
 clearTimeout(TIMER);
}

function decrementTimer(){
 TIMES_UP = false;
 var slider = document.getElementById("divSlider");
 var curLeft = parseInt(slider.style.left);
 if (curLeft < 100) {
  slider.style.left = curLeft + 1 + "px";
  TIMER = setTimeout(decrementTimer, 100);
 } else {
  alert("Time's up!");
  resetTimer();
 }
}
</script>
</head>

<body onload="resetTimer();">

<div id="divSliderBG"><img src="Images/Transparent.gif" 
  height="1" width="1"></div>
<div id="divSlider"><img src="Images/Transparent.gif" 
  height="1" width="1"></div>

<form>
 <input type="button" value="Start Timer" onclick="decrementTimer();">
</form>

</body>
</html>

Exercise: Changing the Math Quiz Timer to a Slider

Duration: 15 to 25 minutes.

In this exercise, you will modify the Math Quiz so that the timer is a slider rather than a count down. The result will look like this:

  1. Open DynamicHtml/Exercises/MathQuizSlider.html for editing.
  2. Notice that the timer on the page has been changed from an input element to two divs.
    <tr id="trTimer">
     <td>Timer:</td>
     <td>
      <div id="divSliderBG"><img src="Images/Transparent.gif"
         height="1" width="1"></div>
      <div id="divSlider"><img src="Images/Transparent.gif"
         height="1" width="1"></div>
     </td>
    </tr>
  3. Also notice that the resetTimer() function sets the width of the slider.
    var slider = document.getElementById("divSlider");
    slider.style.width = "0px";
  4. Modify the decrementTimer() function as follows:
    • Create a variable Slider that holds the divSlider object.
    • Create a variable curWidth that holds the current width of the slider.
    • Within the if block add 1 to the width of the slider.
  5. Test your solution in a browser.

Modify the slider so that it extends the full width of the table cell it is within.

Changing the Z-Index

The z-index of an object can be changed by modifying the zIndex property of the element's style property. The following example demonstrates this.

Code Sample: DynamicHtml/Demos/Zindex.html

<html>
<head>
<title>Position</title>
<style type="text/css">
#divRed {
 position:relative;
 height:100px;
 width:100px;
 z-index:10;
 border:20px solid red;
}
#divBlue {
 position:relative;
 top:-50px;
 height:100px;
 width:100px;
 z-index:20;
 border:20px solid blue;
}
</style>
<script type="text/javascript">
var Z = 20;
function changeZ(elem){
 Z += 10;
 var objElem = elem;
 elem.style.zIndex = Z;
}
</script>
</head>
<body>
<div id="divRed" onclick="changeZ(this);"></div>
<div id="divBlue" onclick="changeZ(this);"></div>
</body>
</html>
Code Explanation

The variable z always holds the highest z-index. The function changeZ() simply adds 10 to z and assigns the resulting value to the zIndex property of the passed in object.

var Z = 20;
function changeZ(elem){
 Z += 10;
 var objElem = elem;
 objElem.style.zIndex = Z;
}

Dynamic HTML Conclusion

In this lesson of the JavaScript tutorial, you have learned to dynamically modify the content of an HTML page and to dynamically modify CSS styles of HTML elements.

To continue to learn JavaScript go to the top of this page and click on the next lesson in this JavaScript Tutorial's Table of Contents.

Use of http://www.learn-javascript-tutorial.com (Website) implies agreement to the following:

Copyright Information

All pages and graphics on Website are the property of Webucator, Inc. unless otherwise specified.

None of the content on Website may be redistributed or reproduced in any way, shape, or form without written permission from Webucator, Inc.

No Printing or saving of pages or content on Website

This content may not be printed or saved. It is for online use only.


Linking to Website

You may link to any of the pages on Website; however, you may not include the content in a frame or iframe without written permission from Webucator, Inc.


Warranties

Website is provided without warranty of any kind. There are no guarantees that use of the site will not be subject to interruptions. All direct or indirect risk related to use of the site is borne entirely by the user. All code and explanations provided on this site are provided without warranties to correctness, performance, fitness, merchantability, and/or any other warranty (whether expressed or implied).


For individual private use only

You agree not to use this online manual to deliver or receive training. If you are delivering or attending a class that is making use of this online manual, you are in violation of our terms of service. Please report any abuse to courseware@webucator.com. If you would like to deliver or receive training using this manual, please fill out the form at http://www.webucator.com/Contact.cfm