mail us  |  mail this page

contact us
training  | 
tech stuff  | 

Tech Stuff - DOM-2 Page Explorer (smasher)

Overview and Background

This was an experiment in DOM programming. We wanted a simple technique where we could look at the DOM page structure and that would work on any page (like this page), would have as few lines of code as possible (we're very lazy) and provide as much info as we could. We looked at passive techniques but they all had problems (a.k.a. needed us to read documents) so we adopted a simple 'semi-intrusive' method that works (with limitations defined below) on any page as long as you have no HTML 'id=' attributes starting with 'z-'. With that simple restriction the deconstructor (we call it smasher) should work just fine on any HTML page. The basic explorer idea is very simple (we're simple folks):

Limitations and Alternate Approaches

There are a number of limitations in the approach we have taken, some just temporary code omissions , some serious design problems depending on what you want to do.


Alternate Approaches

The DOM-2 includes the Traversal and Range Specification which provides NodeIterator, TreeWalker and NodeFilter interfaces to help in navigating a document. An alternative approach may be use a variation on the current approach (direct javascript calls with parameters) which saves and restores state information from one or more of these interfaces may offer a better approach for all nodes. We have not yet had the time to fully investigate.

Code Explanation

To view whole page source. To view the smasher code only.

Function = start()

This function is called when the page is loaded via 'onload=start()' in the body tag. It calls the smash() function to recurse through the document and make sure every element has an id. Page elements are given an id 'z-pX' and display elements 'z-dX' or 'z-aX' (X is a simple incrementing counter).

The function creates the DIV element that will be used as the base for the display and allocates it an id (always z-d0') and a style (dd) which has 'position:absolute;' and 'visibility:hidden;' as well as purely cosmetic attributes. We manipulate these attributes when we display and hide the menu of elements.

Finally we enable the event listener (clicked) for any click event in the browsers window (not document).

Function = smash()

This function is called by start() (to count nodes and allocate an id to all elements but does not display anything), nodex() and clicked() (to format and display elements and nodes). As a consequence it takes a number of parameters which are described in the code.

This function can be recursive (it calls itself based on the supplied parameters). While you do not have to declare variables before use in javascript GECKO's javascript engine REQUIRES explicit definition for a recursive function to work correctly.

When testing for, and allocating, id's we exclude SCRIPT and STYLE elements. This is a limitation (we think) of the W3C spec which says that all elements have ids but the HTML specs says that STYLE and SCRIPT do NOT have ids. If you allocate them the GECKO engine chokes and stops dead.

Since this function looks at every node (via the start() call) we also make it count the nodes to provide some basic stats.

We format and add display nodes via the addnode() function to keep the separation of details clean.

Finally we test for elements with 'id=z-d' and ignore them (these are all associated with the display and NOT the pages elements) to keep the display clean and relevant.

Function = clicked()

This function is called via the Events interface whenever the mouse is clicked. We allow normal (left) clicks for navigation but test for the right mouse button. When this is detected we stop the normal default actions by using the preventDefault method (stops the context menu from being displayed). stopPropagation also gives the same result. MSIE uses the special 'oncontextmenu' event which is added to the body tag.

clicked() gets the base div (id=z-d0) that we created in start(), adds an anchor element to call del() which removes the display, adds a text node for page stats and then calls smash() with the starting document element and the display start node ('z-d0' the div) and no recursion. This results in a display of the top level nodes in the page. Further expansion is by clicking the relevant nodes.

Function = addnode()

A very messy function with too many special cases because of the limitation of the DOM and the method we chose. The function creates and adds nodes to the display. The nodes may be pure text (e.g. page stats), non-element nodes or element nodes.

If the node is pure text its relatively straight forward - we create a text node and append it to the suppled display node.

For all other nodes we use String(node) as a way of serialising the node. We then extract the relevant data from this string (typically returns [class: nodename]').

If its a non-element it cannot take an id attribute so we have to immediately display the interesting bits (in the case of text or comment nodes we just display the full text) whether you want to see them or not. This is not a good solution and it should have a 'Attr' clickable link.

If its an element node we check if it has childNodes and if so we add the anchor node with an href calling the nodex() function ('javascript:nodex(p1, p2)') p1 = the page element 'id' and p2 = the display element 'id' (always a paragraph element). If the element has attributes we add a further anchor node calling the attrex() function with similar parameters.

Due to the limitations of SCRIPT and STYLE elements we have to ignore them (see above) and serializing an anchor element does not give the same result as other nodes so we have to explicitly test for and substitute the string (there must be a better way but we cannot currently find it!).

Function = nodex()

nodex() expands or collapses the element display and is called directly via javascript with all necessary parameters. If the number of childNodes is > 2 (an anchor and text are always present) it assumes a collapse is required so removes nodes until it hits an 'id=z-a' when its stops. For expansion it just calls smash() to do all the work.

Function = attrex()

attrex() expands or collapses the attributes display and is called directly via javascript with all necessary parmeters. If the number of childNodes is > 1 (an anchor is always present) it assumes a collapse is required so removes nodes until it hits an 'id=z-a' when its stops.

For expansion it gets a list of all the elements attributes and loops (using addnode()) to display their 'name' and 'value' attributes. This function looks at each id and if it begins with 'z-' we add the explanatory text (dig) to indicate it was added by smash().

Function = del()

del() removes the display by referencing the base display div (z-d0), changing its visibility attribute to 'hidden' and then loops removing nodes until there are no more childNodes on the div (this leaves only the div node).

Installing on a page

To install the deconstructor on any page do the following:

Load the page and start clicking!

When it all goes horribly wrong

*!#$% happens as we north americans say (brits use the quaint expression 'when it all goes pear shaped') - not that we have any experience of such crises ourselves you understand. You have three great tools to get you out of the stuff both from

Microsoft also have a javascript debugger which we hate because every time you kill the debugger you kill MSIE as well (must be a way around it) but you can get ithere.

Problems, comments, suggestions, corrections (including broken links) or something to add? Please take the time from a busy life to 'mail us' (at top of screen), the webmaster (below) or info-support at zytrax. You will have a warm inner glow for the rest of the day.

Tech Stuff

If you are happy it's OK - but your browser is giving a less than optimal experience on our site. You could, at no charge, upgrade to a W3C standards compliant browser such as Firefox




share page via facebook tweet this page


email us Send to a friend feature print this page Decrease font size Increase font size Display full width page


HTML Stuff

W3C HTML 4.01
HTML5 Reference
W3C Page Validator

CSS Stuff

W3C CSS2.1
W3C CSS2.2
Default Styles
CSS3 Selectors
CSS 3 Media Queries
CSS 3 Colors

DOM Stuff

W3C DOM 3 Core
W3C 3 Events

Web Style Guide

Useful Stuff

Peter-Paul Koch
A List Apart
Eric Meyer on CSS

Our Stuff

Our DOM Pages
DOM Navigation
Liquid Layout
CSS Short Cuts
CSS overview
CSS One Page

Javascript Stuff



CSS Technology SPF Record Conformant Domain
Copyright © 1994 - 2017 ZyTrax, Inc.
All rights reserved. Legal and Privacy
site by zytrax
Hosted by
web-master at zytrax
Page modified: October 21 2015.