Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-16-2013, 01:32 AM   PM User | #1
carevealed
New to the CF scene

 
Join Date: Jan 2013
Posts: 1
Thanks: 1
Thanked 0 Times in 0 Posts
carevealed is an unknown quantity at this point
getElementsByClassName to call multiple classes of same name

I have several sections of content on my site that are default 'hidden' in CSS. I use the getElementById so visitors can open each section of content individually. I now would like to add the option to open ALL content at once. All sections are contained in <div> tags with the class="show". How could I do this with getElementsByClassName?

Here's what I have so far:

function showHideAll(className) {
document.getElementsByClassName(className).style.display = 'block';
}


<a href="#" id="showAll" class="showLink" onclick="showAll('show');return false;">SHOW ALL CONTENT</a>


<div id="content" class="show">CONTENT 1</div>
<div id="content2" class="show">CONTENT 2</div>
<div id="content3" class="show">CONTENT 3</div>

EXAMPLE PAGE:
http://carevealed.com/cc.php
carevealed is offline   Reply With Quote
Old 01-16-2013, 06:15 AM   PM User | #2
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,465
Thanks: 0
Thanked 499 Times in 491 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
getElementsByClassName returns nodelist and not an individual node so what you need is a loop that processes the nodelist to set the style.display to 'block' for each entry in the nodelist.

Code:
function showHideAll(className) {
var n = document.getElementsByClassName(className);
for (var i = n.length-1; i>=0;i--) n[i].style.display = 'block';	
}
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Users who have thanked felgall for this post:
carevealed (01-16-2013)
Old 01-16-2013, 10:19 PM   PM User | #3
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
And we should note that getElementsByClassName is not supported by older MSIE browsers.

So you might want to just stick with getElementsByTagName.

Code:
function showHideAllDivs(className, show) 
{
   var divs = document.getElementsByTagName("div");
   for (var d - 0; d < divs.length; ++d )
   {
        var div = divs[d];
        if ( div.className == className )
        {
            div.style.display = show ? "block" : "none";
         }
    }
    return false;
}
...
<a href-"#" onclick="return showHideAll('show',true);"> Show all </a>
<a href-"#" onclick="return showHideAll('show',false);"> Hide all </a>
You could create a replacement for getElementsByClassName, but if this would be the only use for it on the page, there's not much point.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.

Last edited by Old Pedant; 01-16-2013 at 10:21 PM..
Old Pedant is offline   Reply With Quote
Old 01-17-2013, 12:22 AM   PM User | #4
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,469
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
it would be better to avoid compat problems by simply creating a CSS rule that hides all the classes you want to hide: no loops, no compat issues, and faster performance.


Code:
<style>
body.hide .show { display: none; }
</style>
js:
Code:
document.body.className="hide"; // to hide
document.body.className=""; // to show
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Old 01-17-2013, 12:46 AM   PM User | #5
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Good one, RndMe.

You could also do it a bit more restrictive, if that mattered:
Code:
<style type="text/css">
.hideAll .hide {
    display: none;
}
</style>
...
<div id="holder">
    <div class="hide">...</div>
    <div class="hide">...</div>
    <div class="hide">...</div>
</div>

<a href="#" onclick="document.getElementById('holder').className='hideAll';return false;">Hide all</a>
<a href="#" onclick="document.getElementById('holder').className='';return false;">Show all</a>
You might do it this way if you had multiple "holder" divs where you wanted this kind of control and/or if your <body> needed to be able to change class names for other reasons.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-17-2013, 01:10 AM   PM User | #6
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,465
Thanks: 0
Thanked 499 Times in 491 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
To cater for old IE simply include the following additional code to define getElementsByClassName for when the browser doesn't:

Code:
if (!document.getElementsByClassName)
document.getElementsByClassName = function(cl) {
var retNode, myclass, elem, classes;
retnode = [];
myclass = new RegExp('\\b'+cl+'\\b');
elem = this.getElementsByTagName('*');
for (var i = 0, ii = elem.length; i < ii; i++) {
classes = elem[i].className;
if (myclass.test(classes)) retnode.push(elem[i]);
}
return retnode;
};
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 01-17-2013, 01:14 AM   PM User | #7
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,469
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by felgall View Post
To cater for old IE simply include the following additional code to define getElementsByClassName for when the browser doesn't:

Code:
if (!document.getElementsByClassName)
document.getElementsByClassName = function(cl) {
var retNode, myclass, elem, classes;
retnode = [];
myclass = new RegExp('\\b'+cl+'\\b');
elem = this.getElementsByTagName('*');
for (var i = 0, ii = elem.length; i < ii; i++) {
classes = elem[i].className;
if (myclass.test(classes)) retnode.push(elem[i]);
}
return retnode;
};
good try, but fails.

this is exactly why i recommended using CSS:
Code:
if (!document.getElementsByClassName2) document.getElementsByClassName2 = function(cl) {
	var retNode, myclass, elem, classes;
	retnode = [];
	myclass = new RegExp('\\b' + cl + '\\b');
	elem = this.getElementsByTagName('*');
	for (var i = 0, ii = elem.length; i < ii; i++) {
		classes = elem[i].className;
		if (myclass.test(classes)) retnode.push(elem[i]);
	}
	return retnode;
};

document.body.className="one-active";
alert(
  document.getElementsByClassName2("one")[0].className==="one-active"
);//should be false, but it's true!
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Old 01-17-2013, 01:30 AM   PM User | #8
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Well, we could work harder on that regular expression and correct the problem, but yeah, your CSS trick works a lot better.

FWIW, in my replacement for getElementsByClassName I simply look for the given string to be contained in the className. Yes, I know that means that looking for "one" will incorrectly find "one-active" or even "none" or "lonesome". But that just means I'm really careful about making sure my class names don't have potential problems like that.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-17-2013, 07:47 AM   PM User | #9
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,465
Thanks: 0
Thanked 499 Times in 491 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
Quote:
Originally Posted by rnd me View Post
good try, but fails.
It only fails if you use hyphens in your class names. While - and _ are technically allowed they are not compatible with all browsers. In particular using - in a class can break a lot of JavaScript references to it since it could possibly end up being treated as a minus sign and definitely gets treated as a word boundary.

Anyway if you insist on using hyphens in class names then you could replace the '\\b'+cl+'\\b' in the regexp with '(^| )'+cl+'( |$)' so that it specifically tests just for space and start/end string boundaries. Then your classes would only malfunction in the other places where JavaScript treats the hyphen differently.
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/

Last edited by felgall; 01-17-2013 at 07:55 AM..
felgall is offline   Reply With Quote
Old 01-17-2013, 08:30 AM   PM User | #10
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,469
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by felgall View Post
It only fails if you use hyphens in your class names.

Anyway if you insist on using hyphens in class names then you could replace the '\\b'+cl+'\\b' in the regexp with '(^| )'+cl+'( |$)' ....
my point was that if good coders like you can make mistakes, what else is missing, how much can we rely on such a function, and do we really NEED to hinge our entire operation on such a contraption.

there are other conformance and performance issues with the script, i'm not going to nit pick.

We collectively built a decent one a while back: http://www.codingforums.com/showthread.php?t=154727 (2009)

even still, i think that avoiding loops is always good, avoiding hidden snags is always good, and that CSS offers more precise group definition since its CSS selectors work in IE7 without a bunch of bring-your-own code.

cheers
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 02:01 PM.


Advertisement
Log in to turn off these ads.