Link to home
Start Free TrialLog in
Avatar of Mark Brady
Mark BradyFlag for United States of America

asked on

How to change a childNodes className using javascript

I have this function which is NOT working

function swapClass(loc){
          var obj       = document.getElementById(loc);
      var btnTop       = obj.childNodes[1].className;
      if(btnTop == 'blHourTabTopOFF')
      {
      obj.childNodes[1].className = 'blHourTabTopON');
      } else {
      obj.childNodes[1].className = 'blHourTabTopOFF');
      }
}

Basically this is a mouseover event - I run this function on mouseover and send it the div id name. The function should look at the child element [1] and change the className accordingly.

This is not happening - the script locks up and won't load the whole javascript file.

What I really wanted to do was loop through the children (child) elements inside this <div> and swap the classnames depending on what name they have now. Like an on/off switch. Here is the div container on the HTML page...


<div class="blHourTabCont" id="blt1" style="top:9px" onmouseover="swapClass(this.id)" onmouseout="swapClass(this.id)">
<div class="blHourTabTopOFF"></div>
<div class="blHourTabMidOFF"><div class="blHourTabLabel" id="blHourTabLabel">B</div></div>
<div class="blHourTabBottomOFF"></div>
</div>

1: Why does it go through about 6 items when doing a for loop when there are only 3 child elements (direct decendants) or the parent div ? This has got me confused. When I looped through originally and alerted the classNames, 0 was undefined, 3 undefined, 5 undefined. What are those childNode elements?  I thought my first child would be childNode[0] and so on to childNode[2] but this is not the case.

So I found that with my current div set I have to look for childNodes[1], childNodes[3], and childNodes[6] in order to return the 3 elements that I need to change. Why is this?

Any help changing the classname on these nodes would be appreciated. Basically, I want to change anything ending with 'OFF' to 'ON' and anything ending with 'ON' to 'OFF' and same onmouseout
but when I run my function it does not like changing childNode[1].className for some reason.

Thanks in advance
ASKER CERTIFIED SOLUTION
Avatar of Gregg
Gregg
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Mark Brady

ASKER

Haha I must have made a typo there. There are no ')' characters in my code but thanks for picking that up. I will remove the reference to '.id' and see if it works now. So my function should work then ?

I'll go test it and get right back to you - Thanks for the suggestions.
Good spotting! As it turns out it was the 'this.id' that was causing the problem. Thanks for spotting the mistake,
It was not this.id that gave trouble

This should work too and stop wasting your processing trying to find the object you are passing anyway
function swapClass(obj){ // passing (this) is passing the actual div
    
      var btnTop  = obj.childNodes[1].className; // will not work in firefox if you have whitespace between the divs

      if(btnTop == 'blHourTabTopOFF')
      {
      obj.childNodes[1].className = 'blHourTabTopON';  //elvin66: delete the ) character on this line.
      } else {
      obj.childNodes[1].className = 'blHourTabTopOFF';  //elvin66: delete the ) character on this line.
      }
}

Open in new window

Good point mplungian. I think I was trying to make certain I got the object but yes of course if I'm passing "this" then I have it for sure. Thanks!  As for the firefox thing, I wonder if that is why I am getting "undefined" for childNodes[0] ? There are actually 3 divs inside the main container so I would have thought there would be 3 childNodes from [0] .. [1] and [2] but it is not happening that way. For some reson it is returning undefined for some of those indexes but then again the indexes should not even be there as there are only 3 objects (children) so perhaps Google Chrome is also treating whitespace as a childNodes[] ? Interesting - I'll have to watch out for that. Thanks a lot for the heads up.
Sorry I had to get some breakfast so I did not finish.
I'd do obj.getElementsByTagName("div")[0].className - but give me half an hour
Like this


function swapClass(obj){ 
  var divs = obj.getElementsByTagName("div");
  for (var i=0,n=divs.length;i<n;i++) {
    var className = divs[i].className;
    var on = className.indexOf("ON")!=-1);
    divs[i].className = (on)?className.replace("ON","OFF"):className.replace("OFF","ON");
  } 
}

Open in new window

Damn that is an awesome way of writing the function. I would never have gone down that path at all. Replacing the classname using "replace". Nice touch. The code I have is working fine but I don't know how it will fear across multiple browsers so I think your method here is much safer so thanks buddy, I will use your function instead.
The browser doesn't like this line and locks up...

var on = className.indexOf("ON")!=-1);

I tried putting a space between != and -1 but no luck. What could cause that I wonder, that line looks ok to me.
It could be you have a div without a classname
var on = (className && className.indexOf("ON")!=-1))
function swapClass(obj){ 
  var divs = obj.getElementsByTagName("div");
  for (var i=0,n=divs.length;i<n;i++) {
    var className = divs[i].className;
    if (className) {
      var on =  (className.indexOf("ON")!=-1);
      divs[i].className = (on)?className.replace("ON","OFF"):className.replace("OFF","ON");
    } 
  } 
}

Open in new window

Actually after getting some sleep and reading your first function I found it straight away.  It was a missing parenthesis at the start of this line:

 var on = className.indexOf("ON")!=-1);

should be

 var on = (className.indexOf("ON")!=-1);

But I do agree that you should always use a check beofre assuming something is there  "if(className)"

Thanks for continuing on this question after closed :)
Or a ) too many. Sorry
Yeah right... thanks for the help buddy :)
Sure ... NP