Search code examples
jqueryaddclassremoveclass

Add and removing class on jquery


I am trying to add a class by clicking on specific area and then when i will click on anywhere of body this added class will remove.

I am trying by this code

$(document).ready(function(){

$("ul#nav .have_child").removeClass('sub_more');

    $(".have_child").click(function(){
            $(".have_child").addClass('sub_more')
    });
    $("body").click(function(){
            $(".have_child").removeClass('sub_more')
    });


});

but it does not work.

My HTML code is

<ul id="nav">   
<li class="have_child sub_more">More<i class="fa fa-angle-down"></i>
    <ul class="sub-menu">
        <li><a href="actualpost.html">actualpost</a></li>
    </ul>
</li>

I have founded the solution by using this code

$(document).(function(){
$("ul#nav .have_child").removeClass('sub_more');

$(".have_child").click(function (ev) {
    $('.have_child').toggleClass('sub_more');
    ev.stopPropagation();
});

$("html").click(function () {
    $(".have_child").removeClass('sub_more')
});

});


Solution

  • The problem is that for each click on .have_child elements, two event handlers are fired: first for .have_child, second for body (as the event bubbles). While the first handler adds the class, the second one will remove it immediately after.

    One obvious solution is to disable event propagation in the first ('deeper') handler:

    $(".have_child").click(function(ev){
      $(".have_child").addClass('sub_more');
      ev.stopPropagation();
    });
    

    ... so the handler for body click won't be fired.

    As a sidenote, it'd really be great to check the accompanying HTML structure: it looks a bit strange that you add the corresponding class to all the .have_child elements, and not the clicked one only. In other words, this...

    $(".have_child").click(function(ev){
      $('.have_child').removeClass('sub_more');
      $(this).addClass('sub_more'); 
      ev.stopPropagation();
    });
    

    ... seems more appropriate. Here's a JS Fiddle showing this approach in action.

    Note the (minor) change in that demo: using $('html') instead of $('body') allows to register clicks on the whole document, not just within the dimensions of <body>.