MatthewHSE
Status: Contributor
Joined: 20 Jul 2004
Posts: 122
Location: Central Illinois, typically glued to a computer screen
Back to top
Posted: Oct 11, 05, 13:13    Javascript: Change class name onmouseover / onmouseoff
I'm trying to find a way to use Javascript to find elements with a specific class, dynamically change the class onmouseover, and return the element to its original class onmouseout. Obviously there are a ton of scripts out there that have this kind of functionality, but I need something that I can put into an external javascript, without having to add anything to the markup. I've tried to hack something out, but unfortunately don't know enough about javascript to make it work.

Any ideas?

Thanks,

Matthew
jeffd
Status: Assistant
Joined: 04 Oct 2003
Posts: 594
Back to top
Posted: Oct 11, 05, 14:24    
If you can't touch the onpage code, it's a pain, if you can insert triggers onmouseover/onmouseout =.... it's really easy.

I played around with this for a while, came up with 3 solutions, each has its own posting, this is number 1, fired by onmouseover and onmouseoff events in the tag itself. Check out a sample page of a javascript class switcher here. That version only works in all switch mode in MSIE windows >= 6, the single mode works in MSIE >=5.0

Number 1: requires scripted onmouseover and onmouseoff events in the physical tags

:: Code ::
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>test class switcher</title>
<script type="text/javascript">
function getElementsByClassName(needle) {
   var my_array = document.getElementsByTagName("*");
   var retvalue = new Array();
   var i;
   var j;

   for (i=0,j=0;i<my_array.length;i++) {
      var c = " " + my_array[i].className + " ";
      if (c.indexOf(" " + needle + " ") != -1) retvalue[j++] = my_array[i];
   }
   return retvalue;
}
var classname = 'one';
function toggle()
{
   var divs = getElementsByClassName(classname)
   for(i=0; i <divs.length;i++)
   {
      if(divs[i].className == 'one')
      {
         divs[i].className = 'two';
         classname = 'two';
      }
      else
      {
         divs[i].className = 'one';
         classname = 'one';
      }
   }
   //alert(classname);
}
//alert(classname);
//divs = document.getElementsByTagName('div');

//divs = getElementsByClassName(classname);
//divs.onmouseout = toggle;
//document.onmouseout = toggle;
//divs.onmouseout = toggle;
//divs.onmouseover = toggle;
</script>
<style type="text/css">
div {
   margin:1em;
}
.one {
   background:red;
}
.two {
   background:green;
}
</style>
</head>
   
<body>
<div class="one" onmouseover="toggle();" onmouseout="toggle();">test 1</div>
<div class="one" onmouseover="toggle();" onmouseout="toggle();">test 2</div>
<div class="one" onmouseover="toggle();" onmouseout="toggle();">test 3</div>
<div class="one" onmouseover="toggle();" onmouseout="toggle();">test 4</div>
<div class="one" onmouseover="toggle();" onmouseout="toggle();">test 5</div>

<div class="three">test 6</div>
</body>

</html>
jeffd
Status: Assistant
Joined: 04 Oct 2003
Posts: 594
Back to top
Posted: Oct 11, 05, 14:54    
Number 2: switches all elements of the class only

Here I had to mix 4 different methods I found. Replace the classname, classname1, classname2 with your class names. 'classname' and 'classname1' = to the off state, 'classname2' = on state.

:: Code ::
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>test class switcher</title>
<script type="text/javascript">
var classname = 'one';// this will test the class values, it holds the current value, and should correspond to the off state class
var classname1 = 'one';// static value, change this to your class 1 name
var classname2 = 'two';// static value, change this to your class 2 name
function getElementsByClassName(needle) {
   var my_array = document.getElementsByTagName("*");
   var retvalue = new Array();
   var i;
   var j;

   for (i=0,j=0;i<my_array.length;i++) {
      var c = " " + my_array[i].className + " ";
      if (c.indexOf(" " + needle + " ") != -1) retvalue[j++] = my_array[i];
   }
   return retvalue;
}

function toggle()
{
   var divs = getElementsByClassName(classname)
   for(i=0; i <divs.length;i++)
   {
      if(divs[i].className == classname1)
      {
         divs[i].className = classname2;
         classname = classname2;
      }
      else
      {
         divs[i].className = classname1;
         classname = classname1;
      }
   }
   //alert(classname);
}
function rollon(e) {
   var srcId, srcElement, targetElement;
   if (window.event) e = window.event;
   srcElement = e.srcElement? e.srcElement : e.target;

   if (srcElement.className == classname1)
   {
      toggle();
   }
}
function rolloff(e)
{
   var srcId, srcElement, targetElement;
   if (window.event) e = window.event;
   srcElement = e.srcElement? e.srcElement : e.target;
   if (srcElement.className == classname2) {
      toggle();
   }
}

// assign rollon() to handle onMouseOver events
document.onmouseover = rollon;

// assign rolloff() to handle onMouseOut events
document.onmouseout = rolloff;
</script>
<style type="text/css">
div {
   margin:1em;
}
.one {
   background:red;
}
.two {
   background:green;
}
</style>
</head>
   
<body>
<div class="one">test 1</div>
<div class="one"">test 2</div>
<div class="one">test 3</div>
<div class="one">test 4</div>
<div class="one">test 5</div>

<div class="three">test 6</div>
</body>

</html>


No onpage alterations required, works in MSIE 6, Firefox, Opera 8x. Use at your own risk.
MatthewHSE
Status: Contributor
Joined: 20 Jul 2004
Posts: 122
Location: Central Illinois, typically glued to a computer screen
Back to top
Posted: Oct 13, 05, 4:38    
Thanks, this is just the kind of thing I've been after. Right offhand, do you know of an easy way to adjust the script so that only the element being hovered over changes class? Right now every element changes class when one of them is hovered over, but it would be cool to have some kind of switch in the script so you could choose to alter one or all, depending on the needs of the page.
jeffd
Status: Assistant
Joined: 04 Oct 2003
Posts: 594
Back to top
Posted: Oct 13, 05, 10:23    
Number 3: options for single element or all elements in class switching, this is the one that should be used

The first draft had that, I considered it a bug so I changed it, it's a simple change.

Check out a sample page of a javascript class switcher here. That version only works in all switch mode in MSIE windows >= 6, the single mode works in MSIE >=5.0

:: Code ::
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>javascript class switcher</title>
<script type="text/javascript">
var classname = 'one';// this will test the class values, it holds the current value, and should correspond to the off state class
var classname1 = 'one';// static value, change this to your class 1 name
var classname2 = 'two';// static value, change this to your class 2 name
var feature = 'single';// sets if only hover element or all changes :: options: 'single' or 'all'

// gets all the elements of that have class classname and returns them as an array
function getElementsByClassName(needle)
{
   var my_array = document.getElementsByTagName("*");
   var retvalue = new Array();
   var i;
   var j;

   for (i=0,j=0;i<my_array.length;i++)
   {
      var c = " " + my_array[i].className + " ";
      if (c.indexOf(" " + needle + " ") != -1) retvalue[j++] = my_array[i];
   }
   return retvalue;
}

// if feature is set to all, this will switch all of the class items
// loops through the classname array and switches them to their opposite values
function toggle()
{
   var divs = getElementsByClassName(classname)
   for(i=0; i <divs.length;i++)
   {
      if(divs[i].className == classname1)
      {
         divs[i].className = classname2;
         classname = classname2;
      }
      else
      {
         divs[i].className = classname1;
         classname = classname1;
      }
   }
}

// for onmouseover
function rollon(e)
{
   var srcId, srcElement, targetElement;
   if (window.event) e = window.event;
   srcElement = ( e.srcElement ) ? e.srcElement : e.target;

   if ( srcElement.className == classname1 )
   {
      if ( feature == 'all' )
      {
         toggle();
      }
      else if ( feature == 'single' )
      {
         srcElement.className = classname2;
         classname = classname2;
      }
   }
}
// for mouseoff
function rolloff(e)
{
   var srcId, srcElement, targetElement;
   if (window.event) e = window.event;
   srcElement = ( e.srcElement ) ? e.srcElement : e.target;

   if ( srcElement.className == classname2 )
   {
      if ( feature == 'all' )
      {
         toggle();
      }
      else if ( feature == 'single' )
      {
         srcElement.className = classname1;
         classname = classname1;
      }
   }
}

// assign rollon() to handle onMouseOver events
document.onmouseover = rollon;

// assign rolloff() to handle onMouseOut events
document.onmouseout = rolloff;
</script>
<style type="text/css">
div {
   margin:1em;
}
.one {
   background:red;
}
.two {
   background:green;
}
</style>
</head>
   
<body>
<div class="one">test 1</div>
<div class="one"">test 2</div>
<div class="one">test 3</div>
<div class="one">test 4</div>
<div class="one">test 5</div>

<div class="three">test 6</div>
</body>

</html>



This includes the switch option, for all or single.
Display posts from previous:   

All times are GMT - 8 Hours