Joe Consterdine Joe Consterdine - 3 months ago 8
Javascript Question

Closing element on click outside - What am I doing wrong here?

Just doing a quick test on clicking outside an element with jquery, but having some problems.

I'm trying to remove a class on click outside of an element.

The problem appears to be that the 'document' handler is activating at the same time as the span and therefore not working.

I need it so it works after the class has already been added.

Cheers



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>animation</title>
<link rel="stylesheet" href="css/normalize.css" media="screen" title="no title">
<link rel="stylesheet" href="css/main.css" media="screen" title="no title">
</head>
<body>
<ul>
<li class="top-list"><span>Item</span>
<ul class="sub-top">
<li class="sub-list">Item 1</li>
<li class="sub-list">Item 2</li>
<li class="sub-list">Item 3</li>
<li class="sub-list">Item 4</li>
</ul>
</li>
</ul>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script type="text/javascript">
$("span").on("click", function(){
$(".sub-list").toggleClass("show-menu");
});

$(document).on('click', function(event) {
if (!$(event.target).closest('.sub-list').length) {
$(".sub-list").removeClass("show-menu");
}
});
</script>
</body>
</html>




Answer

You miss ev.stopPropagation() for first handler. You click on span toggle class show-menu, then event bubble into document and thus you click out of .sub-list ( span is out of it ) second handler remove class

Or in second handler you need to check that you click on element out of .sub-list AND not on span element

ul[class]:not(.show-menu) {
  display: none;
 }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>animation</title>
    <link rel="stylesheet" href="css/normalize.css" media="screen" title="no title">
    <link rel="stylesheet" href="css/main.css" media="screen" title="no title">
</head>
<body>
    <ul>
        <li class="top-list"><span>Item</span>
            <ul class="sub-top">
                <li class="sub-list">Item 1</li>
                <li class="sub-list">Item 2</li>
                <li class="sub-list">Item 3</li>
                <li class="sub-list">Item 4</li>
            </ul>
        </li>
    </ul>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="   crossorigin="anonymous"></script>
    <script type="text/javascript">
        $("span").on("click", function(ev){
            $(".sub-top").toggleClass("show-menu");
            ev.stopPropagation();
        });

        $(document).on('click', function(event) {
          if (!$(event.target).closest('.sub-list').length)  {
                $(".sub-top").removeClass("show-menu");
          }
        });
    </script>
</body>
</html>

Information about bubbling can be found here http://javascript.info/tutorial/bubbling-and-capturing