Forum Moderators: open

Message Too Old, No Replies

Hide/show <div> tag problem

         

baroim

12:08 am on May 11, 2010 (gmt 0)

10+ Year Member



Hi guys, im trying to show/hide div tag using the script i found on this forum.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script language=javascript type='text/javascript'>

function showDiv(pass) {
var divs = document.getElementsByTagName('div');
for(i=0;i<divs.length;i++){
if(divs[i].id.match(pass)){//if they are 'see' divs
if (document.getElementById) // DOM3 = IE5, NS6
divs[i].style.visibility="visible";// show/hide
else
if (document.layers) // Netscape 4
document.layers[divs[i]].display = 'visible';
else // IE 4
document.all.divs[i].visibility = 'visible';
} else {
if (document.getElementById)
divs[i].style.visibility="hidden";
else
if (document.layers) // Netscape 4
document.divs[i].visibility = 'hidden';
else // IE 4
document.all.divs[i].visibility = 'hidden';
}
}
}

</script>


</head>

<body>
<a href="javascript:showDiv('F256')">Home</a>
<a href="javascript:showDiv('F512')"> About Us</a>
<div id="F2561" style="position: absolute; left:5px; top:54px; background-color: #0093DD; border: 1px none #000000; visibility: hidden">
Home
</div>

<div id="F512" style="position: absolute; left:5px; top:54px; background-color: #0093DD; border: 1px none #000000" >
About Us
</div>


</body>
</html>



when i tested the above, everything works fine. But when i tested it on my real web, it went wrong. The div tag that i want to show after clicking a link dissapear rather than displayed, not only that specific div tag, but all of div tags were gone. I could post the real code here but it wil be too long. I was wondering if someone could take a look at my pages (only 2mb):

URL REMOVED

I have tried only on the first 2 menus; home and about us. The home div is set to have absolute position and no visibility property being on the landing page. The about us div is set to have absolute position and hidden.

When the about us button is clicked the whole lot went dissapear (only showing the flash banner). My main div consists of other sub divs but without id, only classes, could this be the reason?

Thanks

[edited by: Fotiman at 12:40 am (utc) on May 11, 2010]
[edit reason] No URLs please. See Terms of Service [webmasterworld.com] [/edit]

rainborick

4:06 pm on May 11, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'd start by simplifying the code to remove the backwards compatibility for ancient browsers. It's been 10 years since those non-compatible browsers were replaced, so I think you're pretty safe with something like:

function showDiv(pass) {
state = document.getElementById(pass).style.visibility;
if (state == 'visible') {
document.getElementById(pass).style.visibility = 'hidden';
} else {
document.getElementById(pass).style.visibility = 'visible';
} // endif

} // end showDIV()


The sample code you posted passes the ID of the DIV to be toggled, so there's no need to crawl all of the DIVs in the document for a match. Just be sure that the ID label in the links that call showDIV() actually match the labels in your HTML code. In your example, you call showDIV('F256'), but the HTML code shows <DIV ID="F2561">, which I know was probably just a typo. You may have to explicitly set "visibility:visible;" in the style attribute on the default DIV in order for JavaScript to be able to read/retrieve that value.

rocknbil

6:30 pm on May 11, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Same thing, a little more terse. :-) But I wouldn't use visibility and hidden, it will still take up space, I would use display and block/none.


function showDiv(pass) {
// make sure it exists to avoid JS errors
if (document.getElementById(pass)) {
var obj = document.getElementById(pass);
obj.style.display = (obj.style.display=='block')?'none':'block';
}
return false;
}


A couple notes:

after clicking a link


This link should be a "real" link to something if JS is disabled, but if you simply can't get past that, at least do

<a href="#" onclick="return showDiv('id-of-div');">Show div</a>

Don't do <a href="javascript:void();">

Javascript:void() is not a valid URL.

Second bit about this, return false prevents the page from navigating to the link in the href. Normally # would bring you to the top of the page, by returning false from the function, it will not scroll to top.

The other important part about this bit of code: Javascript will "not be aware" of the state of your div if only set by external style sheets.

#id-of-div { display:none; }

The above code, as is, will fail. So you need to do one of two things: make the style inline (yuk)

<div id="id-of-div" style="display:none">I'm hidden</div>

Or set the style on load:


window.onload=function() {
if (document.getElementById('id-of-div')) {
document.getElementById('id-of-div').style.display="none";
}
};

TheMadScientist

8:26 pm on May 11, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Javascript:void() is not a valid URL.

Hmmm... It does keep the page from reloading, and they use it in an example on the page linked below in the JavaScript (I would link the named anchor, but there isn't one I saw close, but searching for it with FF turns it up in a hurry.).

In the example they do use the # in the original href="" though.

Interestingly it also passes validation with an HTML5 doctype... I haven't tried it in any other to see if the validator is not function correctly with the doctype I'm running, but it certainly didn't throw any type of error when I ran a page through the validator with it present.

http://www.w3.org/TR/WCAG20-TECHS/client-side-script.html [w3.org]

Fotiman

9:01 pm on May 11, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



One problem with "javascript:void()" is that it prevents, for example, bookmarking the link. In most browsers you can right click on a link and add it to your bookmarks/favorites, but what does it mean to add "javascript:void()"?

From the HTML 4.01 Spec:
[w3.org...]
href = uri [CT]
This attribute specifies the location of a Web resource, thus defining a link between the current element (the source anchor) and the destination anchor defined by this attribute.


A URI is defined [ietf.org] to have:
<scheme>:<scheme-specific-part>

But there is no such thing as a "javascript" scheme. The point I would make is that while it may (currently) behave the way you'd like it to, it is technically not really defined, and therefore probably not a good practice to use, especially when there are other methods that accomplish the same thing while not breaking usability (particularly for those with JavaScript disabled).

baroim

9:03 pm on May 11, 2010 (gmt 0)

10+ Year Member



Guys, thanks.

I tried the script suggested by rocknbil. It works to some extent but still not properly.

What works:
1. When the Home / About Us button clicked either div goes off and on.

What dont:
1. When the about Us clicked, the div does appears but in different location rather than on the home div (all div need to be on the exact place to give the impression of content changing)

2. When the About Us clicked, and the div appears, the Home div remains. The Home div need to be gone automaticaly when the About Us shown.

3. The dissapearence of each div is not triggered by other button being clicked, for example to make the About Us div gone, i need to click the About Us button, similar to light switch, to make it off we need to press the same button rather than other.

So far i have implemented the position: absolute on the hidden div, if i put the same on the landing div (home), it moves to other spot not on the right place where it suppose to be.

Any more help guys? thanks.

TheMadScientist

9:10 pm on May 11, 2010 (gmt 0)

Fotiman

1:00 pm on May 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@TheMadScientist, that's interesting (and relatively new). I hadn't heard about that. I still think there are accessibility issues with this method, but I don't want to hijack this thread. I may start a new thread discussion for this. Thanks for the links. :)

Fotiman

2:52 pm on May 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@baroim, in your case a "toggle" function is not exactly what you want.

Here is how I would approach it. First, start with pure markup that is accessible to everyone regardless of whether they have JavaScript or not:


<a href="#F2561">Home</a>
<a href="#F512">About Us</a>
<div id="F2561">
Home
</div>
<div id="F512">
About Us
</div>

(Note: I would probably pick a more meaningful ID for these blocks, like "home" and "aboutus", but perhaps that's not an option for you?)

Next we will use Progressive Enhancement to offer up an enhanced version where clicking a link will show only a particular block.

First, I know that we'll want to walk through the links, so lets give each of those links a unique ID. I'm going to store the IDs of the blocks to be shown/hidden, but I don't need to explicitly hard code those IDs into the script because I can get that information from the href value of the links. I'm going to pull all of the presentational stuff out of the markup. This is better managed by putting it in a separate CSS file (in my example, it's in a style element, but could be improved further by putting it in an external file). All of the JavaScript goes at the end of the file, just before the closing </body> tag (for performance reasons, but also because I am going to get elements that need to be defined first). I could have also used a window onload handler, but instead I'm just using a self-executing function before the closing </body> element (this self executing function also keeps my variables from dirtying the global namespace). Note, I would also put this in an external file as well, but for purposes of this example, the script is simply included in the page.

Below is the finished example. I've tried to comment it well, but if you have questions please ask.


<html>
<head>
<style type="text/css">
#F2561,
#F512 {
background-color: #0093DD;
border: 1px none #000000;
}
.selectedBlock {
position: absolute;
left:5px;
top:54px;
}
.hidden {
display: none;
}
</style>
<title>Test</title>
</head>
<body>
<a href="#F2561" id="homeLink">Home</a>
<a href="#F512" id="aboutUsLink">About Us</a>
<div id="F2561">
Home
</div>
<div id="F512">
About Us
</div>
<script type="text/javascript">
(function () {
var blockIds = [], // the ids of blocks to show/hide
i, // counter for iterating through links
elLink, // temp element reference (attaching handler)
linkIds = ['homeLink', 'aboutUsLink'], // ids of links to attach to
n; // counter for iterating through links
/**
* Hide the blocks represented by the blockIds array, except for the one
* that matches the passed in id.
* @param {string} id The id of the block to remain visible
*/
function showBlock(id) {
var c, // the value of the class name to set
el, // the element to set the class on
i, // counter for iterating through blocks
n; // counter for iterating through blocks
for (i = 0, n = blockIds.length; i < n; i++) {
c = (blockIds[i] === id? 'selectedBlock': 'hidden');
el = document.getElementById(blockIds[i]);
// set class and className for older IE support
el.setAttribute('className', c);
el.setAttribute('class', c);
}
}
// iterate through the links, create the blockIds array,
// and assign onclick handlers to each link
for (i = 0, n = linkIds.length; i < n; i++) {
elLink = document.getElementById(linkIds[i]);
blockIds[i] = (elLink.hash).substr(1);
elLink.onclick = (function (bid) {
return function () {
showBlock(bid);
return false;
}
})(blockIds[i]);
}
// Default to showing the block linked by the first link
showBlock(blockIds[0]);
})();
</script>
</body>
</html>

TheMadScientist

6:34 pm on May 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@ Fontiman...

Sure thing on the links and I know it's new... I read all kinds of stuff and don't always remember where, but usually don't post about something unless I'm fairly certain I've read it from a 'highly reliable' source, which is usually the w3.

I was really not sure about the validator working with HTML5, because I remember reading somewhere on the w3c site about it not doing something correctly with HTML5 doc types all the time yet (prior to HTML5 being recommended, I think?), but was fairly certain the javascript:void(0) was allowed somewhere too, so the discussion just made me figure out where I read it... I think it was one of those late night studies of the HTML5 docs, which seem to change quite a few things.

I think the main thing I take away from it is as I stated in another thread in here: The web is changing and people are going to have to work (change?) to keep up. Totally agree with not hijacking the thread, so I'll leave it here too unless you want to start another one... ;)