[Javascript] Wrestling with DOM access (artificial attributes, IE vs Firefox vs Safari)

Charles Albrecht charles.albrecht at gmail.com
Sat Aug 6 19:44:58 CDT 2005


On 8/6/05, Roger Roelofs <rer at datacompusa.com> wrote:
> Charls,
> 
> On Aug 6, 2005, at 4:33 AM, Charles Albrecht wrote:
> 
> > An example of what I'm working with below is at:
> >   http://euonymic.com/~charlesa/test/menu_test.html
> 
> A sample page would help us give more 'context-sensitive' help, but I
> often abuse the class attribute for this kind of stuff.  The class
> attribute is a space delimited _list_ of values, so you could have
> something like
> 
> <tr id="row512" class="level2 hidecount0 expanded">

Excellent way to get around "won't validate" issue.

On 8/6/05, Triche Osborne <wdlists at triche-osborne.com> wrote:
> 
> I often initialize new instance properties (onload) for form validation.
> I know this works in Moz/FF and IE, though I've not tested in others.
> You could to the same with your TRs, providing it works in the browsers
> you're concerned about. Something like . . .
> 
> function instantiate()
> {
>         var rows = document.getElementsByTagName("tr");
>         for(var i=0; i < rows.length; i++)
>         {
>                 rows[i].newProperty = "initialPropertyValue";
>         }
> }

I'd done some stuff with this, but couldn't seem to get around it.

I combined these two approaches, by attaching a single "state" object
to each row in the onload phase and referencing its properties in my
functions. I've added a new column to the sample page [1] using the
new approach and it works well with all targets I've tested.

My row now looks like:
 <tr id="row512" class="indent_2 hasChildren">

During onload, 

function setinitialstate(selector) {
  var rows = document.getElementById(selector).getElementsByTagName("tr");
  
  var hasindent = /^indent_(\d+)$/;
  for(var i=0; i < rows.length; i++) {
    var row = rows[i];
    var rowstate = new Object;
    
    rowstate.hidelevel = 0;
    rowstate.nextrow = rows[i+1];
    var classes = row.className.split(" ");

    for (var j = 0; j<classes.length; j++) {
      var thisClass = classes[j];
      switch (thisClass) {
         case "haschildren":
           rowstate.isexpanded=true;
           break;
         default:
           var matches = hasindent.exec(thisClass);
           if (matches != null) {
             rowstate.indent = 0;
             rowstate.indent = matches[1];
           } 
           break;      
      }
    }
    row.state = rowstate;
  }
}

And then my toggle code snippet becomes...

  var level = node.state.indent;
  var hiding = node.state.isexpanded;
  
  var leaf = node;
  while ((leaf = leaf.state.nextrow) && (leaf.state.indent > level)) {
    if (hiding) {
      leaf.state.hidelevel++;
    } else {
      leaf.state.hidelevel--;
    }
    
    if (leaf.state.hidelevel > 0) {
      leaf.style.display = "none";
    } else {
      leaf.style.display = "";
    }
  }
  node.state.isexpanded = ! hiding;

... which works on all the browsers I've tested.

Thanks for the pointers.

-Charles
 charles.albrecht at gmail.com

[1] http://euonymic.com/~charlesa/test/menu_test.html



More information about the Javascript mailing list