PDA

View Full Version : Style Swap with Javascript



billyboy
06-14-2006, 10:58 AM
The following code will change the class name of an element (in this case div) when hovered over. By defining the properties for the new class using CSS you can change the style when hovered over.

What I would like to be able to do is target any elements, not just div, that have a particular class already defined. Ideally there would be the option for including more than one class. In other words if an element has a class name "this" change the class name on mouseover to "that" and go back to the original on mouseout, or if an element has a class name "what" change the class name on mouseover to "why", otherwise do nothing.

Writing it inline works <div class="this" onmouseover="className='that'" onmouseout="className='this'"> but I don't wan't to have to add a lot of extra code to my mark up. I honestly am pretty clueless when it comes to javascript and have exhausted my limited knowledge of things to try. I don't even know if I'm on the right track. Anyone feel like taking a stab at it please?

function styleswap(){
var el = document.getElementsByTagName("div");
for (i = [0]; i < el.length; i++) {
el[i].onmouseover=function() {
this.className="jshover";
}
el[i].onmouseout=function() {
this.className="";
}
}
}
window.onload=function(){
styleswap();
}

Twey
06-14-2006, 11:19 AM
/*
Written by Jonathan Snook, http://www.snook.ca/jonathan
Add-ons by Robert Nyman, http://www.robertnyman.com
*/

document.getElementsByClassName = function(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName).
arrReturnElements = new Array();
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
for(var i=0; i<arrElements.length; i++)
if(oRegExp.test(arrElements[i].className))
arrReturnElements.push(arrElements[i]);
return (arrReturnElements);
};

function setClassSwitch(o, f) {
var e = getElementsByClassName(document, "*", o);
for(var i=0;i<e.length;i++) {
e[i].origClass = o;
e[i].hoverClass = f;
e[i].onmouseover = function() {
this.className = this.hoverClass;
};
e[i].onmouseout = function() {
this.className = this.origClass;
};
}
}You definitely want to call that onload.

billyboy
06-14-2006, 01:12 PM
Thanks Twey,
But I keep getting an error Object expected that correspnds to this line:
var e = getElementsByClassName(document, "*", o);

Twey
06-14-2006, 01:19 PM
Sorry, I decided to put the function in document for some reason. That line should be:
var e = document.getElementsByClassName(document, "*", o);

billyboy
06-14-2006, 01:33 PM
Now it's telling me strTagName is undefined here:
var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName).
and length is null or not an object here:
for(var i=0;i<e.length;i++) {

I also don't understand how to say what elements or class I want this to affect:confused:

Twey
06-14-2006, 02:56 PM
OK, let's revert to the original, I've no idea why I wanted to put this in document in the first place.
/*
Written by Jonathan Snook, http://www.snook.ca/jonathan
Add-ons by Robert Nyman, http://www.robertnyman.com
*/

function getElementsByClassName(oElm, strTagName, strClassName) {
var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName),
arrReturnElements = new Array();
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
for(var i=0; i<arrElements.length; i++)
if(oRegExp.test(arrElements[i].className))
arrReturnElements.push(arrElements[i]);
return (arrReturnElements);
}

function setClassSwitch(o, f) {
var e = getElementsByClassName(document, "*", o);
for(var i=0;i<e.length;i++) {
e[i].origClass = o;
e[i].hoverClass = f;
e[i].onmouseover = function() {
this.className = this.hoverClass;
};
e[i].onmouseout = function() {
this.className = this.origClass;
};
}
}

billyboy
06-14-2006, 09:23 PM
I don't get it, now I'm getting an error "undefined is null or not an object":(

I followed the link to the site http://www.robertnyman.com/ and found the code on this pageThe Ultimate getElementsByClassName (http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/) Even if I copy and paste either example of the codes there exactly I still get the same error, so I doubt its the code.

This is from the site:

Some ways to call it
To get all a elements in the document with a “info-links” class.
getElementsByClassName(document, "a", "info-links");
To get all div elements within the element named “container”, with a “col” class.
getElementsByClassName(document.getElementById("container"), "div", "col");
To get all elements within in the document with a “click-me” class.
getElementsByClassName(document, "*", "click-me");
And Twey mentioned

You definitely want to call that onload.
I havent got a clue what to do with the ways to call it from the site, anything I try just causes more errors. So can someone please explain to me exactly I need to do make this work in clear simple steps that some one who does not get javascript will understand. Lets say I have a class "this" that I want change to a class "that" and another class "what" that I want to change to "why" how would I write that in?

Twey
06-14-2006, 09:29 PM
window.onload = function() {
setClassSwitch("this", "that");
setClassSwitch("what", "why");
};

billyboy
06-14-2006, 10:05 PM
Thank you so much Twey! That is absolutely perfect, it does exactly what I need.

billyboy
06-15-2006, 05:44 AM
I've run into a small problem. If I have a class (or classes) assigned to an element already, it seems they get wiped out when moused over and only the class applied by the javascript remains.

For example, if I have the onload function and CSS written like this:
window.onload = (function() {
setClassSwitch("this", "thisHover");
setClassSwitch etc...
})

.center {
text-align: center;
}
.this {
background: #0ff;
}
.thisHover {
background: #fc9;
}Everything is fine in the first div, but the text doesn't stay centered in the second:
<div class="this">Some Text</div>
<div class="this center">Some Text</div>

Twey
06-15-2006, 03:04 PM
We can do that...
function setClassSwitch(o, f) {
var e = getElementsByClassName(document, "*", o);
for(var i=0;i<e.length;i++) {
e[i].origClass = o;
e[i].hoverClass = f;
e[i].onmouseover = function() {
this.className = this.className.replace(this.origClass, this.hoverClass);
};
e[i].onmouseout = function() {
this.className = this.className.replace(this.hoverClass, this.origClass);
};
}
}

billyboy
06-15-2006, 05:53 PM
I think you mean you can can do that don't you ;) Otherwise I wouldn't be here bugging you.

Thanks again Twey, that took care of the problem. I really appreciate all your help!

Can I ask one more thing? I came across this: Executing JavaScript on page load (http://simon.incutio.com/archive/2004/05/26/addLoadEvent). If I understand what he's saying, when you have more than one script, the last one to load will cancel any previous scripts. That bit of code he's written eliminates the problem. Is that right, and is that code he's written worth using instead of just window.onload = (function()?

Twey
06-15-2006, 06:01 PM
His code leaves quite a lot to be desired. Try this instead:
function addEvent(obj, evt, func) {
if(obj.addEventListener) obj.addEventListener(evt, func, false);
else if(obj.attachEvent) obj.attachEvent("on" + evt, func);
else obj['on' + evt] = func;
}

addEvent(
window,
"load",
function() {
setClassSwitch("this", "that");
setClassSwitch("what", "why");
}
);Untested.