Tips and TricksTips and Tricks*
*



Contents  *



Index  *Topic Contents
*Previous Topic: Color Table
*Next Topic: DHTML Tutorials

Tips and Tricks


As with any type of programming, writing bug-free, efficient scripts that meet your expectations takes a bit of work. The following sections provide some tips and hints to make that work take less time and go more smoothly.

arrowr.gifChecking the Internet Explorer Version Number

arrowr.gifCanceling a Button Click

arrowr.gifPreventing a Document From Being Cached

arrowr.gifUsing Objects

arrowr.gifReplacing Custom Controls with Dynamic HTML

Checking the Internet Explorer Version Number

Your scripts should always check the version of the client browser so as to degrade gracefully if the browser does not support the new features of Internet Explorer version 4. The easiest way to identify whether the browser is Internet Explorer and determine its version number is to use the following JScript function:

function msieversion()
// return Microsoft Internet Explorer (major) version number, or 0 for others.
// This function works by finding the "MSIE " string and extracting the version number
// following the space, up to the decimal point for the minor version, which is ignored.
{
    var ua = window.navigator.userAgent
    var msie = ua.indexOf ( "MSIE " )
    if ( msie > 0 )        // is Microsoft Internet Explorer; return version number
        return parseInt ( ua.substring ( msie+5, ua.indexOf ( ".", msie ) ) )
    else
        return 0    // is other browser
}

This function runs on the large majority of browsers and returns the major version number for any Microsoft Internet Explorer browser, or zero for all other browsers. Use of this function assures that the script will be compatible with future versions of Internet Explorer.

Scripts should always check version numbers greater than or equal so as to be compatible with future versions. Existing scripts that check for userAgent equal to "MSIE 3" should be changed to check the version correctly so that these scripts will recognize Internet Explorer 4.0 which supports all of the functionality of the previous version.

The following example shows how to correctly check the client browser version.

if ( msieversion() >= 4 )
    document.alert( "This is IE4 or later - safe to use all IE4 features" )
else if ( msieversion() >= 3 )
    document.alert( "This is IE3 - safe to use ActiveX" )
else
    document.alert( "This is not IE" )

Canceling a Button Click

The following HTML example shows a common scripting mistake related to event handling and canceling the default action.

<HTML>
<HEAD><TITLE>Canceling the Default Action</TITLE>
<SCRIPT LANGUAGE="JScript">
function askConfirm() {
    return window.confirm ("Choose OK to follow hyperlink, Cancel to not.")
}
</SCRIPT>

<BODY onload="b3.onclick=askConfirm">
<!-- Try links with different hookups - should be canceled by "Cancel" to confirm dialog. -->

<BR><A NAME=b1 HREF="http://www.microsoft.com" onclick="askConfirm()">1 Without return (won't work)</A>

<BR><A NAME=b2 HREF="http://www.microsoft.com" onclick="return askConfirm()">2 With return (works)</A>

<BR><A NAME=b3 HREF="http://www.microsoft.com">3 Function pointer (works)</A>

</BODY>
</HTML>

The first A element in this example does not work properly. Without the return in the onclick JScript expression, the browser interprets the function expression, throws away the resulting value (this is just a statement consisting of an expression, no assignment, an so on), and leaves the default action unaffected.

The other A elements correctly bind the return value to the event, hence the default action can be canceled when false is returned.

Preventing a Document From Being Cached

You can prevent a document from being cached by adding the following META tag to the document.

<META HTTP-EQUIV="Expires" CONTENT="0">

Preventing the document from being cached ensures that a fresh copy of the document will always be retrieved from the site, even during the user's current session, regardless of how the user has set his browser's caching options. This is useful if the content of the document changes frequently.

Using Objects

Objects are ActiveX controls or other similar components that provide custom capabilities and services for HTML documents. You can add a control to your document by using the OBJECT element, and gain access to the capabilities and services of the control by using its properties and methods from script.

When using objects, be aware that Dynamic HTML extends every object by providing these additional properties:
align BaseHref
classid code
codeBase codeType
data form
height name
object recordset
type width

If a control has properties with these same names, you will not be able to access the properties unless you preface the name with the object property. For example, assume that an ActiveX control is added to the document by using the following.

<OBJECT ID="MyControl" HEIGHT=100 WIDTH=200 CLASSID="clsid: ... ">
</PARAM NAME="width" VALUE="400">
</OBJECT>

In this example, there are two widths: an extended property set within the OBJECT element, and a property belonging to the control that is set using the PARAM element. To access these from script, you use the following code.

alert(MyControl.width);   // this is Dynamic HTML's property; displays "200"
alert(MyControl.object.width);  // this is the object's property; displays "400"

Replacing Custom Controls with Dynamic HTML

Dynamic HTML provides everything you need to generate animated effects without resorting to custom controls. For example, consider the following script, which is a replacement for the Path control.

var tickDuration;
tickDuration = 50;

var activeObjectCount;
var activeObjects;
var itemDeactivated;

var tickGeneration;

activeObjects = new Array();
activeObjectCount = 0;
timerRefcount = 0;
itemDeactivated = false;

tickGeneration = 0;

function initializePath(e) {
 e.waypointX = new Array();
 e.waypointY = new Array();
 e.duration = new Array();

}

function addWaypoint(e, number, x, y, duration) {
 e.waypointX[number] = x;
 e.waypointY[number] = y;
 e.duration[number] = duration;
}

function compact() {
  var i, n, c;

  n = new Array();
  c = 0;
  itemDeactivated = false;
  for (i=0; i<activeObjectCount; i++)  {
     if (activeObjects[i].active == true) {
        n[c] = activeObjects[i];
        c++;
     }
  }

  activeObjects = n;
  activeObjectCount = c;
}

function tick(generation) {

  if (generation < tickGeneration) {
    // alert("Error "+generation);
     return;
  }

  //alert("tick: "+generation);

  if (itemDeactivated)
     compact();

  if (activeObjectCount == 0) {
     return;
  }
  else {
    for (i=0; i<activeObjectCount; i++) {
      moveElement(activeObjects[i]);
    }

    window.setTimeout("tick("+generation+");", tickDuration);
  }
}

function start(e) {
  if (itemDeactivated)
     compact();

  activeObjects[activeObjectCount] = e;
  activeObjectCount++;

  if (activeObjectCount == 1) { 
    tickGeneration++;
    tick(tickGeneration);
  }
}

function runWaypoint(e, startPoint, endPoint) {

  var startX, startY, endX, endY, duration;

  if (e.waypointX == null)  
    return;   

  startX = e.waypointX[startPoint];
  startY = e.waypointY[startPoint];
  endX = e.waypointX[endPoint];
  endY = e.waypointY[endPoint];

  duration = e.duration[endPoint];
  e.ticks = duration / tickDuration;

  e.endPoint = endPoint;
  e.active = true;
  e.currTick = 0;

  e.dx = (endX - startX) / e.ticks;
  e.dy = (endY - startY) / e.ticks;

  e.style.posLeft = startX;
  e.style.posTop = startY;

  start(e);
}  

function moveElement(e) {
  e.style.posLeft += e.dx;
  e.style.posTop += e.dy;

  e.currTick++;

  if (e.currTick > e.ticks) {
    e.active = false;
    itemDeactivated = true;
    if (e.onpathcomplete != null) {
       window.pathElement = e;
       e.onpathcomplete()
    }
  }
}

To use this script in your document, do the following:

  1. Load the script by using the src attribute of the SCRIPT element.
  2. Initialize the paths by using the initializePath function.
  3. Set the way points by using the addWaypoint function.
  4. Set the path-complete handlers, using the runWaypoint function.

The following sample document show how this works.

<html>

<body>

<div id=Item1 style="position: absolute; left: 0; top: 0;">Item1</div>
<div id=Item2 style="position: absolute; left: 0; top: 0;">Item2</div>
<div id=Item3 style="position: absolute; left: 0; top: 0;">Item3</div>
<div id=Item4 style="position: absolute; left: 0; top: 0;">Item4</div>
<div id=Item5 style="position: absolute; left: 0; top: 0;">Item5</div>
<div id=Item6 style="position: absolute; left: 0; top: 0;">Item6</div>

<input type=button value="Start" onclick="runWaypoint(Item1, 0, 1); runWaypoint(Item2, 0, 1);">
<div id=Debug>Generation</div>

<script src="htmlpath.js">
</script>

<script>

// need to call initializePath on all objects that will be moved with this mechanism
initializePath(Item1);
initializePath(Item2);
initializePath(Item3);
initializePath(Item4);
initializePath(Item5);
initializePath(Item6);

// the 0th waypoint is the intial position for waypoint #1
// syntax is item, waypoint, endx, endy, duration in msecs
addWaypoint(Item1, 0, 0, 0, 0);
addWaypoint(Item1, 1, 200, 200, 2000);

addWaypoint(Item2, 0, 100, 100, 0);
addWaypoint(Item2, 1, 400, 100, 4000);

addWaypoint(Item3, 0, 400, 400, 0);
addWaypoint(Item3, 1, 200, 100, 1000);

addWaypoint(Item4, 0, 0, 0, 0);
addWaypoint(Item4, 1, 200, 200, 2000);

addWaypoint(Item5, 0, 100, 100, 0);
addWaypoint(Item5, 1, 400, 100, 4000);

addWaypoint(Item6, 0, 400, 400, 0);
addWaypoint(Item6, 1, 200, 100, 1000);

function endfunction() {
  // syntax for runWaypoint is Item, start point, end point
  runWaypoint(Item3, 0, 1);
  runWaypoint(Item4, 0, 1);
  runWaypoint(Item5, 0, 1);
  runWaypoint(Item6, 0, 1);

}

function endfunction2() {
  runWaypoint(Item1, 0, 1);
}

Item1.onpathcomplete = endfunction;
Item6.onpathcomplete = endfunction2;

</script>
</body>
</html>



Up Top of Page
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.