简体   繁体   中英

In Javascript, how can I make all triggers initiate a function that only affects their respective child elements?

I'm learning Javascript and I'm sort of getting the hang of it. But I've been trying to do something I haven't found an answer to, probably because it's so basic.

I have a sidebar with three small drop-down menus. Basically three instances of this:

  <ul>
    <li>LEVEL 1
      <button class="sidebtn u1btn">
        <span class="material-icons-round">expand_more</span></button>
    </li>
      <ul class="u1">
        <li><a href="lessons?page=u1">the Weather</a></li>
        <li><a href="lessons?page=u2">Emotions</a></li>
        <li><a href="lessons?page=u3">the Family</a></li>
        <li><a href="lessons?page=u4">Food</a></li>
      </ul>
  </ul>

What I want is for the arrow (ie the span) to flip on click. My first solution was the following:

$('.sidebtn').click(function () {
  $('div.sidebar button.sidebtn span.material-icons-round').toggleClass('flip');
});

However, that obviously makes all three buttons with the .sidebtn class to flip, rather than only the one that was clicked. How can I get a function to affect only the element that fired it off & — for that matter — a child element within it (the span)?

I tried reading up on Javascript, but the information I'm finding is not really targeted for beginners like myself. I see stuff about "event.target" but I'm not sure if that's what I'm supposed to be using here or not. I tried the following with no success:

function flipbtn() {
  event.target.firstChild.toggleClass('flip');

(Of course, having added onclick="flipbtn()" to the HTML.) My thought was that this would toggle the "flip" class for the first child of the element that fired off the function, but the browser says "event.target.firstChild.toggleClass is not a function". I tried the following as well:

const sidebtn = document.querySelectorAll('.sidebtn');

function flipbtn() {
  $(sidebtn).firstChild.toggleClass('flip');
}

But the browser says "$(...).firstChild is undefined". Another thing I tried at some point was using "forEach", but that didn't work either, maybe because I was using it wrong though.

It would be nice to know why these aren't working, because from my vantage point I have a clear idea of what I'm trying to do & my approaches make sense in my head, but obviously they're invalid. But either way, if anyone can tell me how this is supposed to be done, it would be immensely helpful, because I'm totally stumped.

For bonus points, I also want the button to make its respective drop-down menu emerge. Right now it works, but only because I basically hard-coded identifiers for each drop-down menu rather than writing one function that works for everything. So right now it looks like this:

$('.u1btn').click(function () {
  $('ul ul.u1').toggleClass('show');
});

$('.u2btn').click(function () {
  $('ul ul.u2').toggleClass('show');
});

$('.u3btn').click(function () {
  $('ul ul.u3').toggleClass('show');
});

Surely there's a better way. I mean, I could do the same thing for the flip effect, but I'm sure there's a simple way to do this that I'm just not getting right. Thank you so much for your help.

It sounds like you want to use $(this).find :

$('.sidebtn').click(function () {
    $(this).find('span.material-icons-round').toggleClass('flip');
});

Eg. where toggling the class just changes the color to blue:

 $('.sidebtn').click(function () { $(this).find('span.material-icons-round').toggleClass('flip'); });
 .material-icons-round.flip { color: blue; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul> <li>LEVEL 1 <button class="sidebtn u1btn"> <span class="material-icons-round">expand_more</span></button> </li> <ul class="u1"> <li><a href="lessons?page=u1">the Weather</a></li> <li><a href="lessons?page=u2">Emotions</a></li> <li><a href="lessons?page=u3">the Family</a></li> <li><a href="lessons?page=u4">Food</a></li> </ul> <li>LEVEL 2 <button class="sidebtn u1btn"> <span class="material-icons-round">expand_more</span></button> </li> <ul class="u1"> <li><a href="lessons?page=u1">the Weather</a></li> <li><a href="lessons?page=u2">Emotions</a></li> <li><a href="lessons?page=u3">the Family</a></li> <li><a href="lessons?page=u4">Food</a></li> </ul> </ul>

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