I'm trying to create a simple javascript accordion that will let me show/hide <p> paragraphs when I click on an <h2>. When the page is loaded, the <p> are automatically hidden. (This part works ok). When you click on the H2, I want the paragraphs to then appear. Something with the h2 onclick event or either the way I'm calling the DOM is not working. I was hoping for some help/guidance.
HTML:
Code:
<div id="content">
<h2>Header 1</h2>
<p>Here is my header 1 paragraph</p>
<h2>Header 2</h2>
<p>Here is my header 2 paragraph</p>
<h2>Header 3</h2>
<p>Here is my header 3 paragraph</p>
</div>
CSS:
Code:
#content h2 {margin-bottom: 0;}
#content p {margin-top: 0;}
JAVASCRIPT:
Code:
window.onload = function() {
var sectionDiv = document.getElementById('content');
var triggers = sectionDiv.getElementsByTagName('h2');
var paras = sectionDiv.getElementsByTagName('p');
for (var i = 0; i<paras.length;i++) {
paras[i].style.display = "none";
}
for (var i = 0; i<triggers.length;i++) {
triggers[i].style.display = "block";
triggers[i].onclick = function () {
if (this.nextSibling.style.display == "none") {
this.nextSibling.style.display = "block";
} else {
this.nextSibling.style.display = "none"; }
}
}
}
for (var i = 0; i<triggers.length;i++) {
triggers[i].style.display = "block";
triggers[i].onclick = function () {
var sibling=(this.nextSibling.nodeType==3)? this.nextSibling.nextSibling : this.nextSibling;
if (sibling.style.display == "none") {
sibling.style.display = "block";
} else {
sibling.style.display = "none"; }
}
}
I think this is probably close to what I'm looking for but when I try this code, it doesn't work...? The paragraphs are automatically display and the h2 headers don't do anything on click.
I am also trying to understand this line of code:
Code:
var sibling=(this.nextSibling.nodeType==3)? this.nextSibling.nextSibling : this.nextSibling;
The "this" is the h2. It's next sibling is the p tags. You are telling it to grab all the paragraphs who's nodeType is 3 for text nodes? What I'm not sure is what the next bit of code means....
"? this.nextSibling.nextSibling : this.nextSibling;"
Here is an adaptation of something I did before. However, it does the opposite in that the p elements are visible upon start up.
Code:
<html>
<head>
<script type = "text/javascript">
var fred;
function createControl(){
var x = {section: []}; //create generic object containing the section array
var i, num, tmp, v, func;
v = document.body;
num = -1;
for (i =0; i < v.childNodes.length; i++){ //search for all h2 elements place and store ref as new obj in section arr
if(v.childNodes[i].tagName == 'H2'){
num++;
tmp = {p: []};
tmp.header = v.childNodes[i];
tmp.setting = "block";
x.section[num] = tmp;
}
else if(v.childNodes[i].tagName == 'P'){ //store ref to p elements in x.section[].p array
x.section[num].p.push(v.childNodes[i]);
}
}
x.doShift =function(offset){ //determine current setting "none" or "block" from x.section[].settting prop
var len = x.section[offset].p.length;
var j, status;
if(x.section[offset].setting == "block"){
x.section[offset].setting = "none";
}
else{x.section[offset].setting = "block";
}
status = x.section[offset].setting;
for(j = 0; j < len; j++){ //change display setting for p elements
x.section[offset].p[j].style.display = status;
}
}
//----------------------------------------
x.toggle = function(e){ //determine which, if any of the H2 elements was the click source ==x.section[].header
var targ;
if (!e){
var e=window.event;
}
if (e.target){
targ=e.target;
}
else if (e.srcElement){
targ=e.srcElement;
}
if (targ.nodeType==3){
targ = targ.parentNode;
}
var i, len, flag = -1;
len = x.section.length;
for (i = 0; i < len; i++){
if(x.section[i].header === targ){
flag = i;
break;
}
}
if(flag == -1){return;} //if the click didn't originate from an h2 return
x.doShift(flag); //change the display property
}
return x;
}
//var fred;
window.onload = function(){ fred = createControl();}
</script>
</head>
<body onclick ="fred.toggle(event)">
<h2> This is the first</h2>
<p>first of first.</p>
<p>second of first</p>
<p>third of first</p>
<h2>Second</h2>
<p>first of second</p>
<p>second of second</p>
</body>
</html>
Bookmarks