Reputation: 1310
I need help with the following:
I have a page with h3-s and paragraphs and I want all the paragraphs to initially be hidden.
If a h3 is clicked, the script will loop through the tags below it, showing the paragraph tags, if it comes to another h3 tag it should break out the loop.
I have no control over the html output so I can't nest the tags or give any of the h3-s ids. The code below is all i have to play with.
E.g. If H3 Title2 is clicked, then Title 2 Para 1 and Title 2 Para 2 are shown, if H3 Title2 is clicked again then Title 2 Para 1 and Title 2 Para 2 are hidden.
<h3>H3 Title1</h3>
<p>Title 1 Para 1</p>
<p>Title 1 Para 2</p>
<p>Title 1 Para 3</p>
<p>Title 1 Para 4</p>
<h3>H3 Title2</h3>
<p>Title 2 Para 1</p>
<p>Title 2 Para 2</p>
<h3>H3 Title3</h3>
<p>Title 3 Para 1</p>
<p>Title 3 Para 2</p>
<h3>H3 Title4</h3>
<p>Title 4 Para 1</p>
<p>Title 4 Para 2</p>
<p>Title 4 Para 3</p>
No jQuery please
Upvotes: 0
Views: 119
Reputation: 816262
I completely agree with xqwzts' answer: Get a reference to the clicked H3 element, iterate over the following nodes and inspect them (type and name).
Here is another, maybe easier to read solution:
// the event handler we are going to use
var handler = function() {
// `this` refers to the clicked element
var node = this.nextSibling;
// iterate over all following nodes
for(; node ; node = node.nextSibling) {
if(node.nodeName === 'P') {
// if it is a p element, toggle the visibility
node.style.display = node.style.display === 'block' ? '' : 'block';
}
else if(node.nodeName === 'H3') { // or node.nodeType === 1
break; // if it is a H3 element (or an element but not P), stop
}
}
};
// get all h3 elements
var h3s = document.getElementsByTagName('h3');
// assign a click event handler to all of them
for(var i = 0, l = h3s.length; i < l; i++) {
h3s[i].onclick = handler;
}
There are various ways to bind event handlers, all of which are well explained at quirksmode.org.
Reference: getElementsByTagName
, Node#nodeName
, Node#nodeType
, Element#style
Upvotes: 0
Reputation: 66304
Something like..
var pHide = function () {
var ps = document.getElementsByTagName('p'), i = ps.length;
while(i-->0) ps[i].style.display = 'none';
},
toggleDisplay = function (elm) {
elm.style.display = elm.style.display === 'none' ? 'block' : 'none';
},
nextNode = function (elm) { // can't assume built in?
var e = elm;
while( e = e.nextSibling ) if ( e.tagName !== undefined ) break;
return e;
},
addActions = function () {
var hs = document.getElementsByTagName('h3'), i = hs.length;
while(i-->0) hs[i].addEventListener('click',function () {
var elm = this;
while( (elm = nextNode(elm)) && elm.tagName.toLowerCase() != 'h3') if(elm.tagName.toLowerCase() == 'p') toggleDisplay(elm);
}, false);
};
pHide();
addActions();
Example fiddle
Upvotes: 1
Reputation: 3538
Take a look at getElementsByTagName to get all the H3s on your page, you want to attach a click() handler to those.
In your onclick you loop over all the next elements until you get to an H3 and break out of the loop. Take a look at nextElementSibling for getting the elements after the H3.
For showing/hiding either set a css class or directly change the element's style toggling between display:block
and display:none
.
Upvotes: 2