DHTML stands for Dynamic HTML. The dynamic part indicates the ability to modify the content of a page after it has been rendered by the client. This includes the ability to move elements, change colors, fonts, and sizes, cause elements to appear and disappear, and respond to user input through the mouse and keyboard.
Control over positioning of elements has been dramatically increased with the introduction of CSS-P (Cascading Style Sheets-Positioning) in 1997. By adding positioning to the style properties of an element, programmers can take advantage of the ability to specify display coordinates for any element. Through scripts, these can often be changed after the initial rendering of the document. Three major style properties that control placement are 'position', 'top', and 'left'.
The position style property is one of 'absolute', 'relative', or 'static'. The top and left properties specify the location of the top/left corner of an element. The meaning of top and left depends on the position value. Absolute positioning means top and left are distances from the top-left corner of the elements positioned container (i.e. a containing element that also specifies a style position). If the element is not inside a positioned container, then these coordinates are measured from the top-left of the frame. In the following example, absolute positioning is used to place text over an image. Notice that both the text paragraph and the image use absolute positioning that starts at the top left of the table cell which is their common positioned container.
<td style="position: relative; height:200"> <img src="AppliedSystems.jpg" style="position: absolute; top: 10px; left: 30px;"> <h3 id="sampletext" style="position: absolute; top: 10px; left: 30px;"> This text will appear over the image that is displayed as a separate element in this cell of the table. </h3> </td> |
This text will appear over the image that is displayed as a separate element in this cell of the table. |
Elements positioned absolutely or relatively may be repositioned via script by accessing the DOM object and changing the top and left property values. The buttons
can be used to move the text in the table above. Each click increases or decreases the element's left property value by 10.
function shift(amt){
var x=document.getElementById("sampletext").style;
x.left=parseInt(x.left)+amt; } Note how the position information is a property of the element's style object. The parseInt function is needed as the position data includes units (i.e. 10px) and is therefore not a number! |
The above example used relative positioning to locate the table cell. Relative positioning means top and left are distances from the default rendering location of the element. Since top and left are not set, the table cell is located as if no positioning were specified. However, it does become a positioned container which affects the meaning of the positioning information for its contents. In addition, these elements can be repositioned later through a script.
The default position value is static. This means the element is positioned initially according to the usual HTML layout conventions. In addition, this type of element cannot be later repositioned. Statically positioned elements may not specify top or left.
Visibility of an element is controlled by its style visibility attribute. Set it to [ 'visible' or 'hidden' ]. You will need to click the button below to see the possible values for visibility in the previous sentence!
Access to the color and font properties are also common. These attributes are often used to create special effects when the mouse is moved over an area of the screen. This paragraph, for example, changes colors each time the mouse moves over it.
Simple animation can be achieved by repeatedly changing an element's position slightly. JavaScript includes a timeout timer and an interval timer that can be used to animate elements. The timeout timer is a one-shot timer useful for causing an event after a delay (like an alarm clock's alarm). The interval timer is used to repeat an action on a regular basis (like advance the second hand on a clock). The actual timer object is instantiated by a method call (in the Window object) that returns a reference to the timer object. You need to keep track of it to start and stop the timer.
myAlarmTimer = setTimeout("code();", 30000);
|
Create and start a one-shot timer set to execute the function call to code in 30 seconds (30000 milliseconds) |
myIntervalTimer = setInterval("code();", 100);
|
Create and start an interval timer set to execute the function call to code 10 times per second (every 100 milliseconds) |
The timers may be removed from the Window using their associated clear methods:
clearTimeout(myAlarmTimer); |
clearInterval(myIntervalTimer); |
The following table contains a bouncing O. Feel free to Start and Stop it at will.
O |
Here is most of the relevant code
//global variables var otimer=null; //the timer reference var ball=null; //the bouncing ball var yinc=1; //control direction of vertical movement var xinc=1; //control direction of horizontal movement var xmax=0; //to be set later var ymax=0; function bounce(){
var t=parseInt(ball.top); var l=parseInt(ball.left); if (t<-10)yinc=1; //reverse direction if needed else if (t>=ymax)yinc=-1; if (l<-5)xinc=1; else if (l>=xmax)xinc=-1; //move ball 1 pixel in current direction ball.top=t+yinc; ball.left=l+xinc; } function motion(go){
if (go && !otimer){//init globals and timer
ball=document.getElementById('ball').style;
xmax=box.width-25; //determine box bounds ymax=box.height-30; otimer = setInterval("bounce();",10); //create/start timer
} else{ //reset timer and mark as unused
clearInterval(otimer); otimer=null; } } //The buttons call motion with true or false arguments |
| Using the visibility and positioning capability, an invisible textarea can be used to show information when certain events occur. Mouse over the italicized words in this paragraph to see various messages appear to the right. The technique used here is to modify the textual content of a paragraph tag. This is possible through DOM . |
|
<script type='text/javascript'> function show(t){
helper=document.getElementById('help'); //get paragraph element
if (t) helper.firstChild.nodeValue=t; //replace text else helper.firstChild.nodeValue=""; } var msg1="Visibility - the property... var msg2="Events such as... etc., </script> HTML <span onmouseout="show(false);" onmouseover="show(msg1);"> <i>visibility</i> </span> Similarly for other hot-words. The paragraph tag in the table has some non-breaking spaces to ensure that it is registered in the document tree. <p id="help" style="position: relative; top:0; left:0;"> </p> |
|
When elements (positioned absolute or relative) are rendered at the same position or overlap, the browser must decide which is on top. This is determined through the element's z-index attribute. The JavaScript style object uses zIndex to correspond to the CSS style attribute. Elements with greater z-index values will be displayed on top of elements with lesser ones. Elements with identical z-index values will be drawn in the order they are encountered, hence the last one will be on top. Elements with no z-index attribute are positioned below those with a positive z-index, and above those with a negative z-index. The following script would set the z-index of an element with id "elt" to -1, moving it behind elements with a greater z-index and those with none.
document.getElementById("elt").style.zIndex = -1;
So far, our event handlers have been passed element references or variables or constant values. It is possible to pass the Event object to the handler. This object contains information about the event. Of particular interest is information about the mouse at the time of a mouse-related event. Consider the following event handler that is activated by a mouse movement in the body of the paragraph:
<p onmousemove="mousedetective(event);">Mouse movement anywhere...
Mouse movement anywhere in this paragraph will create an Event object with properties that include the coordinates of the click (relative to the browser client or the screen). You can click in this paragraph to see what happens. The textbox to the right will display the results of each click. Note that a complete understanding of the generation and propagation of events in nested elements is complicated by the event model in use. |
|
function mousedetective(evt){
var mdtext= //access textbox document.getElementById("mousedata");
mdtext.value="("
+evt.clientX+", "+evt.clientY +"), ("
+evt.screenX+", "+evt.screenY +")"; } |
Older event models provided attributes named offsetX, offsetY or simply X, Y to tell the coordinates within the element in which the mouse event occurred. The Event object also contains a reference to the element that triggered the event: srcElement. In the example above, this would be the paragraph element.
Using the mouseup, mousedown, and mousemove events, you can implement drag-and-drop operations. The images below can be repositioned using the mouse.
function pickup(e){
da=document.getElementById("dragarea").style;
xmin=parseInt(da.left); ymin=parseInt(da.top); dragging=e.srcElement; xmax=parseInt(da.width)+xmin -parseInt(dragging.width); ymax=parseInt(da.height)+xmin -parseInt(dragging.height); yref=e.clientY-parseInt(dragging.style.top); xref=e.clientX-parseInt(dragging.style.left); } function drag(e){
if (dragging){
var y=e.clientY-yref; var x=e.clientX-xref; if (x>=xmin && x<=xmax) dragging.style.left=x; if (y>=ymin && y<=ymax) dragging.style.top=y; } } function drop(){
dragging=null; } |
In this example, the mousedown event (pickup(event)) places
the object reference in a global variable that indicates the dragged
object. This variable is null if nothing is being dragged. The mouseup
event (drop()) removes this dragged object reference. The mousemove event
(drag(event)) is used to change the position of the dragged object to
match the mouse position (as long as there is a dragged object).
This uses the DOM-0 event model and is not likely to work anywhere but IE. |
<div style="position: relative; top:0; left:0; background: yellow; border: solid; width:500; height: 300" id="dragarea" onmousemove="drag(event); return false;" > <p> <img onmousedown="pickup(event); return false;" onmouseup="drop(); return false;" style="position:absolute; top:0; left:0;" src="question.gif" width="90" height="88"> <img onmousedown="pickup(event); return false;" onmouseup="drop(); return false;" style="position:absolute; top:0; left:0;" src="no.gif" width="90" height="88"> <p> </div> |
|