getElementsByClassName - for multiple classes (e.g class="foo bar")

hi all,

im on a really tight deadline with this and have been strugglign all day.
(i know nothing about JS!)

here’s my code:


<script language="Javascript">
var allHTMLTags = new Array();
function fadeIn(SRC) {
var allHTMLTags=document.getElementsByTagName("*");
for (i=0; i<allHTMLTags.length; i++) {
if (allHTMLTags[i].className.indexOf(SRC) !== -1) 
{
allHTMLTags[i].style.opacity='1';
}
}
}

function fadeOut(SRC) {
var allHTMLTags=document.getElementsByTagName("*");
for (i=0; i<allHTMLTags.length; i++) {
if (allHTMLTags[i].className.indexOf(SRC) !== -1) 
{
allHTMLTags[i].style.opacity='0.5';
}
}
}
</script>


<li onMouseover="fadeIn(foo)" onmouseout="fadeOut(foo)">

<div class="foo" style="opacity: 0.5;">
test 1
</div>

<div class="foo bar" style="opacity: 0.5;">
test 2
</div>

<li onMouseover=“fadeIn(‘foo’)” onmouseout=“fadeOut(‘foo’)”>

Will make it work for a single class. If you want to make it work for multiple classes, you’ll have to split() SRC and loop through each class to compare.

What exactly are you trying to accomplish with the code?

sorry if i wasnt very clear.

basically, i have 3 classes:

brand, experience, digital

then a list. some of the list items will have 1 class, or 2, or all 3.

i need 3 divs, that when hovered over, make the relevant list items have an opacity of 1.

E.G -
you hover over a div called “brand” and all of the list items who’s class CONTAINS “brand” should light up. onMouseOut they should return to 0.5 (they could be <li class=“brand digital”> and because it contains “brand” the script picks this up and applies an opacity of 1 to that item. (and all the other items containing that class name)

does that make sense?

thanks so much for your prompt response!

First, you should make a function called hasClass(el, class). indexOf is a bad way of matching classnames, because it would return true for a partial match (e.g. the class “foo-bar” would match a test for class “foo”).


function hasClass(el, class) {
	class = class.toLowerCase()
	var classNames = el.className.toLowerCase();
	classNames = classNames.split(" ");
	for (var i = 0; i < classNames.length; i++) {
		if (class == classNames[i]) return true;
	}
	return false;
}

Then your fadeIn / out functions should be altered to use that function. You can reduce fade() to one function for simplicity:


function fade(class, fadeIn) {
	var els = document.getElementsByTagName("*");
	for (var i = 0; i < els.length; i++) {
		if (hasClass(els[i], class))  {
			els[i].style.opacity = fadeIn ? '1.0' : '0.5';
		}
	}
}

And finally, update your html to reference your new function:


<li onMouseover="fade('foo', true)" onmouseout="fade('foo', false)">

thank you!

but how do i put that all together?
at the moment it looks like 2 functions? :S

sorry im really rubbish with JS

never mind!
it works PERFECTLY as is. thank you so much!

one last thing though…how do i change it slightly, so that all the <li>'s are set to opacity 1.
then on:hover the ones that DONT have the classname fade to 0.5 and the ones that do stay at 1? (then they all go back to 1 onMouseOut)


function fade(class, fadeIn) {
	var els = document.getElementsByTagName("li");
	for (var i = 0; i < els.length; i++) {
		els[i].style.opacity = (hasClass(els[i], class) || !fadeIn) ? '1.0' : '0.5';
	}
}

me again!
this doesnt seem to work in IE?
it says “fade is undefined”?

any ideas how to make this x browser compatible?

(also that last piece of code you gave makes everything on the page fade to 0.5 and nothing to 1?)

here’s the full error:
SCRIPT1010: Expected identifier
line 108 character 23: function hasClass(el, class) {
LOG: [cycle] terminating; zero elements found by selector

here’s my full code now:


<script language="Javascript">
function hasClass(el, class) {
	class = class.toLowerCase()
	var classNames = el.className.toLowerCase();
	classNames = classNames.split(" ");
	for (var i = 0; i < classNames.length; i++) {
		if (class == classNames[i]) return true;
	}
	return false;
}

function fade(class, fadeIn) {
	var els = document.getElementsByTagName("li");
	for (var i = 0; i < els.length; i++) {
		els[i].style.opacity = (hasClass(els[i], class) || !fadeIn) ? '1.0' : '0.5';
	}
}
</script>

<li onMouseover="fade('CategoryBrand', true)" onmouseout="fade('CategoryBrand', false)"> test </li>

<li>
<img class="CategoryBrand CategoryExperiential CategoryDigital " width="100" height="100" alt="" src="test.png">
</li>


and this doesnt work in IE. fine in FF though.

sorry THIS is the code that works in FF & Chrome but not Safari or IE:


<script language="Javascript">
function hasClass(el, class) {
	class = class.toLowerCase()
	var classNames = el.className.toLowerCase();
	classNames = classNames.split(" ");
	for (var i = 0; i < classNames.length; i++) {
		if (class == classNames[i]) return true;
	}
	return false;
}
function fade(class, fadeIn) {
	var els = document.getElementsByTagName("*");
	for (var i = 0; i < els.length; i++) {
		if (hasClass(els[i], class))  {
			els[i].style.opacity = fadeIn ? '1.0' : '0.5';
		}
	}
}
</script>

If it says “fade is undefined” in IE you may have another piece of javascript that’s causing the JS engine to shut down. That’s the only thing that I can think of… I don’t see how the code above could cause an error in IE.

Try stripping out your other JS and putting it back bit by bit to debug (IE doesn’t have a great way to debug JS unfortunately).

Get that working and then we’ll figure out the other issue.

this is the only other JS on my page:


$(document).ready(function() {
$('.slideshow').cycle({
fx: 'scrollLeft' // choose your transition type, ex: fade, scrollUp, shuffle, etc...
});
}); 

i just removed all of the JS on my site, and it still doesnt work in IE :frowning:

SCRIPT1010: Expected identifier
?flush=1, line 108 character 23
SCRIPT5009: ‘fade’ is undefined
?flush=1, line 131 character 22

including external scripts?

i think i see the problem…

change <script language=“javascript”> to <script type=“text/javascript”>

that may fix it.

npoe that wasnt it :frowning:

does it HAVE to be in the head or anything?


			  <script type="text/javascript">
function hasClass(el, class) {
	class = class.toLowerCase()
	var classNames = el.className.toLowerCase();
	classNames = classNames.split(" ");
	for (var i = 0; i < classNames.length; i++) {
		if (class == classNames[i]) return true;
	}
	return false;
}
function fade(class, fadeIn) {
	var els = document.getElementsByTagName("*");
	for (var i = 0; i < els.length; i++) {
		if (hasClass(els[i], class))  {
			els[i].style.opacity = fadeIn ? '1.0' : '0.5';
		}
	}
}
</script>

did some testing and figured it out… “class” is a reserved word :wink: try this:


var hasClass = function (el, cl) {
	cl = cl.toLowerCase()
	var classNames = el.className.toLowerCase();
	classNames = classNames.split(" ");
	for (var i = 0; i < classNames.length; i++) {
		if (cl == classNames[i]) return true;
	}
	return false;
}

function fade(cl, fadeIn) {
	var els = document.getElementsByTagName("li");
	for (var i = 0; i < els.length; i++) {
		els[i].style.opacity = (hasClass(els[i], cl) || !fadeIn) ? '1.0' : '0.5';
	}
}