简体   繁体   中英

JavaScript - Toggle classes based on click event

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

CodePen

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM