I'm working on improving my JavaScript after using jQuery so much. I'm trying to toggle visibility of a list of elements based on what the user clicks on.
Here is a Code Pen example: http://codepen.io/sdejaneiro/pen/BjEVBQ?editors=1000
In the example, what I want to do is, when clicking on "Part 1 Item C" (or Part 2 Item C or Part 3 Item) (which has class series
) I want to show the Sub-items below it (which are contained inside a ul
list with classes seriesSet
and hidden
. I've gotten as far as attaching a click even to each instance of the class series
but am not sure how to target the correct seriesSet
. I tried using a forEach attached to each instance of seriesSet
, but that ended up triggering all the ul
lists with that class all at once.
I want to try and keep the code as clean as possible, so I avoided adding ids to the seriesSet
lists, but maybe I do need something like that for JavaScript?
Here is the JavaScript:
NodeList.prototype.forEach = Array.prototype.forEach;
//toggle series lists
document.querySelectorAll('.series').forEach(function(i) {
i.addEventListener('click', function(e) {
e.preventDefault();
//select the correct .seriesSet ul list and remove class "hidden"
})
});
这应该可以满足您的要求
e.target.children[0].classList.toggle("hidden");
Another way is to use jQuery:
$('.series').click(function () {
$(this).find('.seriesSet').toogleClass('hidden');
});
Edit: Sorry, I haven't read the first sentence... :/
Using the firstElementChild as the selector for the ul elements withing the clicked list item element. Then test for the hidden class.
NodeList.prototype.forEach = Array.prototype.forEach;
//toggle series lists
document.querySelectorAll('.series').forEach(function(i) {
i.addEventListener('click', function(e) {
var ch = this.firstElementChild;
e.preventDefault();
//select the correct .seriesSet ul list and remove class "hidden"
if (/hidden/.test(ch.className)) ch.className = 'seriesSet';
else ch.className = 'seriesSet hidden';
})
});
I would capture the list items text in an element like a span, or an a-tag though, that way you're able to prevent the sub-items from toggling the menu back up.
Maybe something like this
var series = document.querySelectorAll('.series');
for (var i = 0; i < series.length; i++) {
series[i].addEventListener('click', function(e) {
e.preventDefault();
updateSub(this);
})
}
function updateSub(el) {
for (var i = 0; i < series.length; i++) {
if (series[i] == el) {
el.childNodes[1].classList.toggle('hidden');
} else {
series[i].childNodes[1].classList.add('hidden');
}
}
}
The cleanest approach would be to do something like this :
var tree = document.querySelectorAll('ul.series a:not(:last-child)'); for(var i = 0; i < tree.length; i++){ tree[i].addEventListener('click', function(e) { var parent = e.target.parentElement; var classList = parent.classList; if(classList.contains("open")) { classList.remove('open'); var opensubs = parent.querySelectorAll(':scope .open'); for(var i = 0; i < opensubs.length; i++){ opensubs[i].classList.remove('open'); } } else { classList.add('open'); } }); }
body { font-family: Arial; } ul.series li { list-style-type: none; position: relative; } ul.series li ul { display: none; } ul.series li.open > ul { display: block; } ul.series li a { color: black; text-decoration: none; } ul.series li a:before { height: 1em; padding:0 .1em; font-size: .8em; display: block; position: absolute; left: -1.3em; top: .2em; } ul.series li > a:not(:last-child):before { content: '+'; } ul.series li.open > a:not(:last-child):before { content: '-'; }
<ul class="series"> <li><a href="#">Part 1</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> <li><a href="#">Part 2</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> <li><a href="#">Part 3</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> </ul>
(see also this Fiddle )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.