DHTML Lab: Accessing the User-Defined System Colors, Part I - dhtmlab.com | 12 | WebReference

DHTML Lab: Accessing the User-Defined System Colors, Part I - dhtmlab.com | 12


Accessing the User-Defined System Colors, Part I

The short script that controls the active/inactive state of our dialogs should be included at the end of the HTML page, since it assumes the existence of the dialog elements.

Making an Element Active

Toggling the state of a dialog is fairly simple. It requires:

  1. a variable to track the active dialog: activeElement
  2. a function to color the newly-active dialog and the previously-active dialog: makeActive()
  3. an initial call to makeActive() to set the default active dialog.
activeElement = null;
function makeActive(el){
  if (activeElement) {
    activeElement.children(0).style.borderColor = "inactiveborder";
    activeElement.children(1).style.backgroundColor = "inactivecaption";
    activeElement.children(1).style.color = "inactivecaptiontext";
  el.style.zIndex = (activeElement) ? (activeElement.style.zIndex+1) : 1;
  el.children(0).style.borderColor = "activeborder";
  el.children(1).style.backgroundColor = "activecaption";
  el.children(1).style.color = "captiontext";
  activeElement = el;

First, activeElement is initialized and set to null.

Then, we define makeActive(). Recall that makeActive() is called whenever we mouse down on a dialog element, and we pass one argument, the dialog containing element:


Therefore, when makeActive() is called, it first checks for an existing activeElement. The first time makeActive() is called, activeElement is null, so the three lines in the if statement are ignored. In subsequent calls, these lines are executed, and they color the activeElement to reflect an inactive state, before the function goes on to color the new activeElement.

The border element of each dialog is the first child element in the dialog element. That is, it is the first contained element defined in the HTML. The caption element is the second element. We identify them by their position (0 and 1, respectively) in the dialog element's children collection.

We then proceed to give the dialog border an inactiveborder color value, the caption background an inactivecaption value and the caption text an inactivecaptiontext value. The active dialog is now an inactive one, using the OS color scheme.

Once the active dialog has been made inactive, we proceed to make the element passed to the function (el) active.

First we place the new active element over the inactive element by assigning it a z-index larger than that of the inactive element. Next, we identify the active element's border and caption elements, and color them active using activeborder, activecaption and captiontext.

Finally, we assign the new active element to the activeElement variable.

With makeActive() defined, our script then calls makeActive(), passing popup1 as the argument, making popup1 the active dialog.

Displaying the Menus

The menu script has three parts as well:

  1. a variable to track the current menu bar selection: activeMenu.
  2. a function to color the menu bar and display/hide the appropriate drop-down menu: setMenu().
  3. a function to restore the menu bar and hide any visible menu if the user clicks outside the menu: killMenu().
activeMenu = null;
function setMenu(el){
   if (activeMenu) {
      activeMenu.menuElement.style.visibility = "hidden";
      activeMenu.style.backgroundColor = "menu";
      activeMenu.style.color = "menutext";
   el.style.backgroundColor = "highlight";
   el.style.color = "highlighttext";
   switch (el.id) {
      case "span1":
         el.menuElement = menu1;
      case "span2":
         el.menuElement = menu2;
      case "span3":
         el.menuElement = menu3;
   el.menuElement.style.pixelLeft = el.offsetLeft+2;
   el.menuElement.style.visibility = "visible"
   activeMenu = el;
   document.onmousedown = killMenu;
   event.cancelBubble = true;   
function killMenu(){
   activeMenu.menuElement.style.visibility = "hidden";
   activeMenu.style.backgroundColor = "menu";
   activeMenu.style.color = "menutext";
   activeMenu = null;
   document.onmousedown = null;

First we initialize activeMenu with null.

The setMenu() function takes one argument, the SPAN element in the menu bar. Recall that each SPAN in the menu bar has this event handler:


The first thing setMenu() does is make the dialog the SPAN element is in active. The SPANs mousedown is fired before the full element's. The most convenient way to handle the event is to cancel the full dialog's handling of it with event.cancelBubble = true;. If we do not cancel it, then it will be called after setMenu() runs its course. We want to make the dialog active before we do anything else. So we call makeActive() ourselves and cancel the later automatic call.

We pass makeActive() an argument of el.offsetParent.offsetParent, to identify the full dialog. The menu bar SPAN element (el) is nested two-levels deep in the element hierarchy, so we have to move two levels up (two offsetParents) to identify the dialog element.

Once we have made the dialog active, we check for an active menu, which will not exist if there is no drop-down menu visible. As we shall see, the current SPAN element (activeMenu) is assigned a drop-down menu later in the function. This drop-down menu is stored as the menuElement property of the activeMenu. Therefore, if activeMenu exists, its menuElement (drop-down menu) is hidden, and activeMenu gets the default background/text colors of menu and menutext.

The function moves on to color the SPAN element that called it (el). The element's background color is set to highlight and its text to highlighttext.

Then we check the element's ID in a switch statement and accordingly assign a drop-down menu to its menuElement property.

Now we know which drop-down menu to display, so we position it to line up with the SPAN and make it visible.

The SPAN element is then assigned to activeMenu, for global identification, and the complete page's onmousedown handler is set to call killMenu(). Meaning that, if a menu is visible, any mousedown in the document will call killMenu().

The killMenu() function hides the drop-down menu, restores the menu bar SPAN element to the default colors, assigns null to activeMenu, since no drop-down menu is visible, and cancels the document.onmousedown handler for the same reason.

The Close (X) Button

Recall that the close button had these event handlers:

onMouseDown="xPress(this,1)" onMouseUp="xPress(this,0)"

The xPress() function looks like this:

function xPress(el,on) {
   el.style.borderStyle = (on) ? "inset" : "outset";
   event.cancelBubble = true;

It simply toggles the border style between inset and outset to create the depressed/raised effect. We also cancel the event bubbling, so the dialog element will not receive the mousedown, which makes it active by calling makeActive(). The close button closes a dialog, so no further statement should be executed.

In a real-world script, the close button would also have an onClick() handler that closed the dialog.


To enable dialog dragging, we have included a short, customized version of our drag-drop script, fully discussed in column 7. We have excluded Navigator code, and added four statements to the beginning of grabEl(), called whenever the dialog caption fires a mousedown.

These statements:

  1. hide a drop-down menu if one is visible: if (activeMenu) killMenu();
  2. identify the dialog to be dragged: whichEl = el;, and
  3. make it active before initiating drag: makeActive(whichEl);
    currentX = currentY = null;
    whichEl = null;
    function grabEl(el) {
       if (activeMenu) killMenu();
       whichEl = el;
       event.cancelBubble = true;
       whichEl.style.pixelLeft = whichEl.offsetLeft;
       whichEl.style.pixelTop = whichEl.offsetTop;
       currentX = (event.clientX + document.body.scrollLeft);
       currentY = (event.clientY + document.body.scrollTop); 
       document.onmousemove = moveEl;
       document.onmouseup = dropEl;
       event.returnValue = false;   
    function moveEl() {
       newX = (event.clientX + document.body.scrollLeft);
       newY = (event.clientY + document.body.scrollTop);
       distanceX = (newX - currentX);
       distanceY = (newY - currentY);
       currentX = newX;
       currentY = newY;
       whichEl.style.pixelLeft += distanceX;
       whichEl.style.pixelTop += distanceY;
       event.returnValue = false;
    function dropEl() {
       document.onmousemove = document.onmouseup = null;

    The complete HTML and script will be repeated on our final page, after we experience the dialogs live once more.

    Produced by Peter Belesis and

    All Rights Reserved. Legal Notices.
    Created: Feb 23, 1999
    Revised: Feb 23, 1999

    URL: http://www.webreference.com/dhtml/column24/colsIEexample8.html