Search code examples
javascriptjqueryjquery-eventsevent-bubbling

jQuery or Javascript along hide element if visible when clicking on the body else where


I am trying to close a make shift drop down menu when someone clicks elsewhere on the site. Only if it's found to be open. However the below snippet seems to misfire and lock the browser. So I think I am coming at this wrong. Is there a better way to handle this notion?

$(document.body).click(function() {
    if($('#ztsWidgetMenu').is(':visible'))
    {   
        $('#addDashWidgetBox').click();
    }
});

EDIT

I made a function to fire off on the click event now for both the element to open it, and the body click to call to, the bubbling stops with that however I ran into another problem with it now. In order to open the menu I need to click on the menu item at least twice for it to open the menu. And if I click on the same button to close it then I am stuck with it open unless I click on the body else where now..

function openCloseWidgetMenu()
{
        dashboardJSON.widgets.sort(sortJSONresultsByWidgetID);  
        if(widgetMenuShowHide == "hide")
        {
            widgetMenuShowHide = "shown";
            $.each(dashboardJSON.widgets, function(x)
            {
                if(dashboardJSON.widgets[x].show == "no"){$('#ztsWidgetMenu ul').append('<li class="widgetMenuItems" rel="'+dashboardJSON.widgets[x].wigetID+'" widgetcolor="'+dashboardJSON.widgets[x].widgetColor+'">'+dashboardJSON.widgets[x].widgetTitle+'</li>');}
            });
            $('#ztsWidgetMenu').css({"display":"block", "position":"absolute", "left":($('#addDashWidgetBox').position().left-35) + "px", "top":($('#addDashWidgetBox').offset().top+$('#addDashWidgetBox').height()+10) + "px"});
        }
        else
        {
            $('#ztsWidgetMenu ul li').remove();
            $('#ztsWidgetMenu').hide();
            widgetMenuShowHide = "hide";
        }
}
$('#addDashWidgetBox').live({
    click: function()
    {
        //e.preventDefault();
        openCloseWidgetMenu();
    },
    mouseover: function()
    {
        $('#addWidetMenuBar').css({"background-position":"-0px -697px"});
        $(this).css({"color":"#000"});
    },
    mouseout: function()
    {
        $('#addWidetMenuBar').css({"background-position":"-0px -662px"});
        $(this).css({"color":"#5a5a5a"});
    }
});

$(document.body).click(function() {
    if($('#ztsWidgetMenu').is(':visible'))
    {   
        openCloseWidgetMenu();
    }
});

Edit 2

I have fixed my issue for the most part, except now.. when I click on the element I want to fire off the function to show the menu the body click registers at the same time so now its firing the same function off twice with one click.


Solution

  • I'm assuming this is being caused by Event Bubbling..

    when #addDashWidgetBox is "clicked" by your code, it's also causing the body to be clicked which puts you in an infinite loop.

    just be more specific about what you want to happen...

    Instead of simulating user input ( via your manual .click() ), just be more explicit

    $(document.body).click(function() {
        if($('#ztsWidgetMenu').is(':visible'))
        {   
            //Call functions being fired by the simulated click directly...
        }
    });