ro_orco
ro_orco

Reputation: 33

In Jquery, why children react to function for parent?

I would like the children to be hidden when parent is clicked again but not when children are clicked. For some reason children are treated as $level1 elements while I was expecting them not to respond to $level1.click function. I think I'm missing something trivial, but I can't help myself. Here you are the filddle https://jsfiddle.net/bxmbtzrb/3 Thank you for your suggestions.

The structure

<nav>
      <ul>
        <li>
          <a>PARENT</a>
          <ul>
            <li>
              <a href="#">CHILD 1</a>
            </li>
            <li>
              <a href="#">CHILD 2</a>
            </li>
            <li>
              <a href="#">CHILD 3</a>
            </li>
          </ul>
        </li>
      </ul>

The Jquery script:

var $level1 =$('nav').children('ul').children('li');
  $level1.click(function() {
    if ($(this).hasClass('on')) {
      $(this).removeClass('on');
    } else {
      $level1.filter('.on').removeClass('on');
      $(this).addClass('on');
    }
  });
    nav li:not(.on) li {
      display: none;
    }

and CSS:

nav li:not(.on) li {
  display: none;
}

Upvotes: 0

Views: 62

Answers (2)

Pierre-Adrien Maison
Pierre-Adrien Maison

Reputation: 610

Firstly, your children are treated as '$level1' elements because of your jQuery selector : var $level1 =$('nav').children('ul').children('li'); --> Your event is triggered on click on your selected 'li' AND all its childrens.

You can use tricks to check if it's the parent who fire the event (How to have click event ONLY fire on parent DIV, not children?), but I suggest you an other way to do what you want.

//You get your parent 'li' element
var list = $('nav').children('ul').children('li');
//You get your 'a' element, the one who have to fire the event
var $level1 = list.children('a');

//Init the event
$level1.click(function() {
    //Add or Remove the 'on' class of the parent list
    list.toggleClass('on');
});

You have your fiddle updated here : https://jsfiddle.net/bxmbtzrb/25/

Upvotes: 1

Sharmila Jesupaul
Sharmila Jesupaul

Reputation: 131

your $level1 selector, contains everything inside your first list, including the children, which is why the children also hide after being clicked.

I would recommend using an id on the parent and using that as a selector. If you can't do that then select the first child link:

var $level1 =$('nav > ul > li > a:first-child');
var children =$('nav > ul > li');
$level1.click(function() {
  $(children).toggleClass('on');
});
 
nav li:not(.on) li {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
  <ul>
    <li>
      <a>PARENT</a>
      <ul>
        <li>
          <a href="#">CHILD 1</a>
        </li>
        <li>
          <a href="#">CHILD 2</a>
        </li>
        <li>
          <a href="#">CHILD 3</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Upvotes: 1

Related Questions