[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1258
  • Last Modified:

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
0
Mark Brady
Asked:
Mark Brady
  • 7
  • 7
1 Solution
 
GreggCommented:

<html>

<head>

<script language="javascript" type="text/javascript">
function swapClass(loc){

      //elvin66: Move the reference to .id to javascript. as shown below:
      var obj = document.getElementById(loc.id);
      
      //simple test
      if(!obj) alert("not found");
      var btnTop  = obj.childNodes[1].className;

      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.
      }
}
</script>
</head>
<body>
<div class="blHourTabCont" id="blt1" style="top:9px" onmouseover="swapClass(this)" onmouseout="swapClass(this)">
<div class="blHourTabTopOFF"></div>
<div class="blHourTabMidOFF">
	<div class="blHourTabLabel" id="blHourTabLabel">B</div>
</div>
<div class="blHourTabBottomOFF"></div>
</div>

</body>
</html>

Open in new window


Does this help you?
0
 
Mark BradyAuthor Commented:
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.
0
 
Mark BradyAuthor Commented:
Good spotting! As it turns out it was the 'this.id' that was causing the problem. Thanks for spotting the mistake,
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Michel PlungjanIT ExpertCommented:
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

0
 
Mark BradyAuthor Commented:
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.
0
 
Michel PlungjanIT ExpertCommented:
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
0
 
Michel PlungjanIT ExpertCommented:
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

0
 
Mark BradyAuthor Commented:
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.
0
 
Mark BradyAuthor Commented:
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.
0
 
Michel PlungjanIT ExpertCommented:
It could be you have a div without a classname
var on = (className && className.indexOf("ON")!=-1))
0
 
Michel PlungjanIT ExpertCommented:
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

0
 
Mark BradyAuthor Commented:
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 :)
0
 
Michel PlungjanIT ExpertCommented:
Or a ) too many. Sorry
0
 
Mark BradyAuthor Commented:
Yeah right... thanks for the help buddy :)
0
 
Michel PlungjanIT ExpertCommented:
Sure ... NP
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now