I've transplanted Toggling Element Visiblity from its old home on the Mindsack; kindly update your bookmarks.
Please do read the source; it's all obsessively commented and ought to be pretty self-explanatory. Here are some of the highlights:
toggle. If we find one that says toggle closed, we immediately hide its next sibling element, by styling it with class name hidden.toggle, closed, and hidden) are fed in at the bottom in the init call, and may be changed to any valid class name.That's it! With only a single global variable we're making a good-faith attempt to stay out of the general namespace, and we're not capturing any far-reaching events like document.onmousedown so it ought to work and play nicely with other scripts. Naturally you should feel free to change my KENTBREW.toggle object namespace to whatever you like.
<html> <head> <title>My Toggled Page</title> <link rel="stylesheet" type="text/css" href="toggle.css" /> </head> <body> <dl> <dt class="toggle">This is an open headline.</dt> <dd>This will hide if the headline above is toggled.</dd> <dt class="toggle closed">This is a closed headline</dt> <dd>This will show if the headline above is toggled.</dd> </dl> <script type="text/javascript" src="toggle.js"></script> </body> </html>
.toggle {
background: transparent url('norgie_open.gif') .25em .25em no-repeat;
text-indent: 20px;
cursor:pointer;
}
.toggle.closed {
background: transparent url('norgie_closed.gif') .25em .25em no-repeat;
}
.hidden {
display:none;
}
// toggling event visibility
// v5 Kent Brewster, 7/11/2006
// questions? comments? dirty jokes?
// please leave 'em here:
// http://kentbrewster.com/toggle
// feel free to use or abuse this code
// but please leave this notice intact
// namespace protection: one global variable to rule them all
var KENTBREW = window.KENTBREW || {};
KENTBREW.toggle = function() {
// private bucket for scope-sensitive variables -- thanks, Dustin
var $ = {};
return {
init : function(selfObj, toggleClass, toggleClosed, toggleHidden) {
// first, a brute-force hack to decode the calling function's
// name and store it upstairs, safe from scope creep
$.selfName = this.getSelfName(selfObj);
// we're going to hang all variables that might be confused
// by scope changes later onto KENTBREW.variables, which is aliased to $.
// In this case it's three class names, fed in from the init call:
$.toggleClass = toggleClass;
$.toggleClosed = toggleClosed;
$.toggleHidden = toggleHidden;
// crawl through the document, look for toggled elements
this.crawl(document.body);
},
crawl : function(el) {
// get this element's next sibling
var nextSib = this.getNextSibling(el);
// if it has a class name, the class name matches our toggle class, and there's something there to toggle:
if (el.className && el.className.match($.toggleClass) && nextSib)
{
// to avoid scope loss, attach onmouseup to the toggle function with eval and $.selfName
el.onmouseup = function () {
eval($.selfName + '.toggleState(this)');
};
// if the next sib ought to be hidden and it isn't already, hide it
if (el.className.match($.toggleClosed) && nextSib && !nextSib.className.match($.toggleHidden)) {
nextSib.className += ' ' + $.toggleHidden;
}
}
// is there more to do? Do it, if so:
if (el.firstChild) {
this.crawl(el.firstChild);
}
if (nextSib) {
this.crawl(nextSib);
}
},
toggleState : function(el) {
// change the style of the triggering element
if(el.className.match($.toggleClosed)) {
el.className = el.className.replace($.toggleClosed, '');
}
else {
el.className = el.className + ' ' + $.toggleClosed;
}
// the norgie we clicked has changed. Now we need to
// change the style of its parent node's next sibling
var nextSib = this.getNextSibling(el);
// check if it's really there; other scripts could have removed it
if(nextSib && nextSib.className.match($.toggleHidden)) {
nextSib.className = nextSib.className.replace($.toggleHidden, '');
}
else {
nextSib.className += ' ' + $.toggleHidden;
}
},
getNextSibling : function(el) {
var nextSib = el.nextSibling;
// hack for Gecko browsers
if (nextSib && nextSib.nodeType != 1) {
nextSib = nextSib.nextSibling;
}
return nextSib;
},
getSelfName : function(selfObj) {
// icky hack to get contents of selfObj into a string
// suggestions will be gratefully appreciated
var s = document.createElement('SPAN');
s.innerHTML = selfObj;
// cut the fat, split the meat to namespace array
var nameSpace = s.innerHTML.split('{')[1].split('(')[0].replace(/^\s+/, '').split('.');
var selfName = '';
// here we assume that the main function is up one level from the init function
for (var i = 0; i < nameSpace.length - 1; i++) {
if (selfName) {
selfName += '.';
}
selfName += nameSpace[i];
}
return selfName;
}
};
}();
// feed it the CSS class names of your choice
window.onload = function() {
KENTBREW.toggle.init(arguments.callee, 'toggle', 'closed', 'hidden');
}();