views:

311

answers:

2

I am using the jQuery function

function ShowHide(){
  $(".login").animate({"height": "toggle"}, { duration: 1000 });
}

and the link to show hide the .login div is:

onclick="ShowHide(); return false;"

But this link only toggles the div to show and hide, but I want it to also hide when the user clicks off the div, I have a page wrapper in place but just need some help with jQuery.

+1  A: 

you need to put event on body element to hide it, if you want user clicking anywhere else to hide it.

ps: please, do not use onclick in the html elements! - use event manager in jquery for that (e.g. sth. in the lines of addevent (click, function) )

dusoft
Could you please provide an example markup for this?
chris
You want something like $('#myLink').click(ShowHide);
John McCollum
I appologise as i am very new to Jquery and am at beginner stage, and I understand using onlick in html is bad practice, and would really appreciate it, if you could show me an example of the best practice method, thanks very much
chris
No problem :) There's a good primer here: http://stackoverflow.com/questions/621574/jquery-why-unobtrusive-javascript-document-ready-function-rather-than-onclick
John McCollum
Why not use onclick? Seems to me this provides an easier way to find which handlers are bound to which elements.
recursive
because using onclick directly goes against separation of content from events and sometimes hurts accessibility as well.
dusoft
+2  A: 
<html>
    <head>
    <script type="text/javascript" src="jquery-1.3.2.js"></script>
    <style>
        .login-div { width: 100px; height: 100px; margin:auto; border: solid 1px black; position: relative; background-color: #aeaeae;  display:none;}
        .parent-div { width: 300px; height: 300px; margin:auto; border: solid 1px #aeaeae; position: relative;}
        .footer { margin-bottom: 0px; margin-top:auto; margin-left:auto; margin-right:auto; height:40px; width:200px; position:relative; display:none;}
    </style>
    <script>
        $(window).load(function(){
            var DEBUG = 0;
            var count = 0;
            $('.parent-div').bind('click', function(e){
                e.preventDefault();
                e.stopPropagation();
                DEBUG==1?console.log('Target: '+$(e.target).attr('class')):'';
                DEBUG==1?console.log('Show Hide: '+(count++)):'';
                //ShowHide();
                var target_class = $(e.target).attr('class');
                if(target_class == 'link'){
                    $(".login-div").animate({"height": "toggle"}, { duration: 1000 });
                    $('.footer').toggle();
                }
                else{
                    $(".login-div").animate({"height": "hide"}, { duration: 1000 });
                    $('.footer').hide();
                }
            });
        });
    </script>
    </head>
    <body>
        <div class="parent-div">Parent Box:<br/>
            <a href="#" class="link">ShowHide</a>
            <div class="login-div">Child Box:</div>
            <div class="footer">click out side the gray box & inside the Parent-box
        </div>
    </body>
</html>


I rigged up the above based on my understanding of your requirement, check out the code. this should do your job. Here I am using "click" event bubbling in java script and have a event listener bound to parent-div class element. this same can be attached to <body/> if the scope of elements is to be increased.

Ajaxe
Ajaxe
event bubbling and propagation gets complicated, if you have multiple onclick events on the page and attach onclick event on the body, but the example should help you.
dusoft
I agree with dusoft, going higher on the DOM will result in more calls to the 'click' handler on 'body', also somewhere in 'bubbling' chain on one of the child elements may `event.stopPropagation()` wherein the required handler is never called and DIV in question never hides/shows. Event handling chains have to be considered.
Ajaxe