Warning: XSLTProcessor::transformToXml() [function.XSLTProcessor-transformToXml]: I/O warning : failed to load external entity "/home/webucato/courseSourceFiles/JavaScript/ClassFiles/DynamicHtml/Demos/table.html" in /home/webucato/public_html/xslt.inc.php on line 29

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.

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.

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

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");
 }
}

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>

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 this website implies agreement to the following:

Copyright Information

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

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

No Printing or saving of web pages

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


Linking to this website

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


Warranties

This 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.