Attach event handler to all elements except one and its descendants










-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.










share|improve this question
























  • 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 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











  • stackoverflow.com/questions/152975/…

    – 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(); [api.jquery.com/closest/]

    – danbae
    Nov 14 '18 at 18:56















-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.










share|improve this question
























  • 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 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











  • stackoverflow.com/questions/152975/…

    – 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(); [api.jquery.com/closest/]

    – danbae
    Nov 14 '18 at 18:56













-1












-1








-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.










share|improve this question
















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.







jquery html






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 23:05







danbae

















asked Nov 14 '18 at 18:11









danbaedanbae

62110




62110












  • 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 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











  • stackoverflow.com/questions/152975/…

    – 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(); [api.jquery.com/closest/]

    – danbae
    Nov 14 '18 at 18:56

















  • 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 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











  • stackoverflow.com/questions/152975/…

    – 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(); [api.jquery.com/closest/]

    – danbae
    Nov 14 '18 at 18:56
















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 codereview.stackexchange.com

– Taplar
Nov 14 '18 at 18:13





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 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





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




1





event delegation would be so much better than all those click handlers being added.

– epascarello
Nov 14 '18 at 18:20





event delegation would be so much better than all those click handlers being added.

– epascarello
Nov 14 '18 at 18:20













stackoverflow.com/questions/152975/…

– epascarello
Nov 14 '18 at 18:21





stackoverflow.com/questions/152975/…

– 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(); [api.jquery.com/closest/]

– danbae
Nov 14 '18 at 18:56





@epascarello: Thanks for the reference. the closest selector did the trick: if($(this).closest("#div1").length == 0)$("#div1").hide(); [api.jquery.com/closest/]

– danbae
Nov 14 '18 at 18:56












1 Answer
1






active

oldest

votes


















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;

);
);





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306397%2fattach-event-handler-to-all-elements-except-one-and-its-descendants%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    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;

    );
    );





    share|improve this answer





























      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;

      );
      );





      share|improve this answer



























        0












        0








        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;

        );
        );





        share|improve this answer















        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;

        );
        );






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 14 '18 at 21:42

























        answered Nov 14 '18 at 20:56









        danbaedanbae

        62110




        62110





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306397%2fattach-event-handler-to-all-elements-except-one-and-its-descendants%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

            Museum of Modern and Contemporary Art of Trento and Rovereto