-1

Seemingly simple problem: I'm working on a Chrome extension that has a help "window" – actually a div – that is shown upon a menu action. Now I want that divto be hidden again when the user clicks outside of the div. Thus any click on the divor its descendant elements should be ignored and all others should trigger hiding of the div. This is the only solution I have found that works, but it is ever so inelegant and circumstantial (later edit: this code prevents clicking on other elements from having effect, so it is also dysfunctional in addition to being clumsy).

 <html>
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
    var flag = 0;//controls whether hiding is allowed

        $("#div1").click(function(){//clicks on div1 should be ignored
          flag = 1;//prevent hiding by third function
        });

        $("#div1").find("*").click(function(){//clicks on descendants of div1 should be ignored 
          flag = 1;//prevent hiding by third function
        });

        $("*").click(function(){//captures all clicks
          if(flag == 1){flag = 0;}//reset flag for next event
          else {$("#div1").hide();}//if allowed, hide
        return false;
        });        
    });
    </script>
    </head>
    <body>    

    <div id="div1" style="border:1px solid black;padding:10px;">
      <p>This is a div. It should go away when you click outside of it.</p>
    </div>
    <p></p>
    <div id="div2" style="border:1px solid black;padding:10px;">
      <p>This is another div. <span>If you click on it, or anywhere else outside of the div above, that div should go away.</span></p>
    </div>

    </body>
    </html>

I'm sure there are better solutions. I have looked at previous posts "Select all elements that are not descendant of a certain class" and "Use jQuery to get descendants of an element that are not children of a container with a certain CSS class", but I can't make them work in this context.

danbae
  • 563
  • 2
  • 8
  • 22
  • If the code works as it is, and you can show a working example, and you are asking if there is a way to make it better, then this is off topic for Stack Overflow, and you should consider posting the question on https://codereview.stackexchange.com/ – Taplar Nov 14 '18 at 18:13
  • you can set a class to the descendant you want to ignore and then set an if : `if($(this).hasClass('yourClass'))` – Mojo Allmighty Nov 14 '18 at 18:13
  • 1
    event delegation would be so much better than all those click handlers being added. – epascarello Nov 14 '18 at 18:20
  • https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element – epascarello Nov 14 '18 at 18:21
  • @epascarello: Thanks for the reference. the `closest` selector did the trick: `if($(this).closest("#div1").length == 0){$("#div1").hide();}` [http://api.jquery.com/closest/] – danbae Nov 14 '18 at 18:56
  • Good work. Be sure to provide and accept an answer or close your question so it's resolved. – isherwood Nov 14 '18 at 20:26

1 Answers1

0

This is what seems to work eventually; the code above did produce some unexpected results by preventing subsequent clicks, so I think it's OK to keep the question on StackOverflow.

 $(document).ready(function(){
    $("*").click(function(){
    if($(this).closest("#div1").length == 0) {
      if($("div#div1").css("display") != "none"){
        $("div#div1").hide();
        return false;
      }
    } else {
      return false;
    }
   });
 });
danbae
  • 563
  • 2
  • 8
  • 22