0

I have a button that toggles a menu popup. I have can make the menu disappear if you click outside of the menu but now my button toggle does not work. If I click the button again the menu stays up. How can I make the menu disappear if you toggle the button or if you click off the container?

jsFiddle: http://jsfiddle.net/PPcfN/

$('.quicklinks-rollover').click(function () {
    $('.quicklinks').toggle();
});
$(document).mouseup(function (e) {
    var container = $(".quicklinks");
    if (container.has(e.target).length === 0) {
        container.hide();
    }
});
Guilherme Oderdenge
  • 4,935
  • 6
  • 61
  • 96
Chaddly
  • 267
  • 1
  • 6
  • 18
  • hope you can use "display:none" CSS property – Able Alias Jul 16 '13 at 12:57
  • 1
    FYI: .toggle() is now deprecated. – emerson.marini Jul 16 '13 at 12:58
  • oh, i was not aware. what is the alternative now? – Chaddly Jul 16 '13 at 12:59
  • Chaddly, [the alternative is here](http://forum.jquery.com/topic/beginner-function-toggle-deprecated-what-to-use-instead). Or, a cleaner and easier solution [is here](http://stackoverflow.com/questions/14338078/equivalent-of-deprecated-jquery-toggle-event). – Guilherme Oderdenge Jul 16 '13 at 12:59
  • toggle is not deprecated! .toggle(function, function, ... ) removed This is the "click an element to run the specified functions" signature of .toggle(). It should not be confused with the "change the visibility of an element" of .toggle() which is not deprecated. The former is being removed to reduce confusion and improve the potential for modularity in the library. The jQuery Migrate plugin can be used to restore the functionality. – raam86 Jul 16 '13 at 13:01

4 Answers4

1

The mouseup function has to take care of the click on the button (quicklinks-rollover). If fixed the whole thing here: http://jsfiddle.net/8VUnq/1/

$(document).mouseup(function (e) {
    var popup = $('#quickLinksPopup'),
        button = $('#quickLinksToggle');
    if (popup.is(':visible')
        && !popup.is(e.target)
        && !button.is(e.target)
        && popup.has(e.target).length === 0
        && button.has(e.target).length === 0) {
        popup.toggle();
    }
});

Keep in mind those two things:

  1. Use IDs to refer to the items quicker and prevent multiple popup conflicts
  2. Using a mouse event on the whole page is not recommended as the event will get triggered very frequently, try using an alternative method such as adding a close button in the popup, or to be more effective, think about adding the mouseup listener on the show of the popup and removing it on the hide.

You can determine the state of the popup with: $(popup).is(':visible') or is(':hidden').

Tibo
  • 988
  • 7
  • 9
  • quick question. if this is not an easy thing let me know and i'll consider making a new thread. Can I use $('.quicklinks-rollover').hover(function () {}); to make it appear transparent as you hover over the button? Or will this require restructure? – Chaddly Jul 16 '13 at 14:25
  • All you need for that is to add the opacity setting to the class on the hover state. `.quicklinks-rollover:hover {opacity: .4; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; alpha(opacity=40);}` This will set 40% of opacity on IE7+ and other browsers. But the :hover will not work on IE6 as it is applied to a button and not a link. – Tibo Jul 18 '13 at 13:27
  • Sorry, I meant if you hover hover the button the menu appears visable and transparent. The option you've provided makes my button transparent when hovering it. – Chaddly Jul 18 '13 at 17:25
  • I would use the `$().hover()` function on the button to add a specific class to the menu and change the CSS so that when this class is present, the popup is visible and transparent. Consider using the two arguments taken by `hover()` for managing "hover" and "out" to add/remove the class. You might have an issue with the hover of the button while the popup is already open (hovering out might close the menu), so try it to find what you consider a convenient behavior for your users. – Tibo Jul 18 '13 at 18:36
0

Try :

var $quicklinks = $('.quicklinks');
var msOverLinks = false;

$('.quicklinks-rollover').click(function () {
    $quicklinks.toggle();
});

$quicklinks.mouseenter(function() {
    msOverLinks = true;
}).mouseleave(function() {
    msOverLinks = false;
});

$(document).mouseup(function (e) {
    if( ! msOverLinks ) {
        $quicklinks.toggle();
    }
});
Virus721
  • 8,061
  • 12
  • 67
  • 123
0

You can do this Normal hide and show method. Because mostly toggle() function wont works in proper manner...

put your HTML button with attribute p="closed" by default:

      <button class="quicklinks-rollover" p="closed" title="Quick Links">toggle</button>

Change Your Jquery:

         $('.quicklinks-rollover').click(function () {
             var a = $(this).attr("p");
             var container = $(".quicklinks");
             if(a=="closed"){
              container.show();
              $(this).attr("p","open");
            }else{
              container.hide();
              $(this).attr("p","closed");
            }
       });
     $(document).mouseup(function (e) {
       var container = $(".quicklinks");
       if (container.has(e.target).length === 0) {
           container.hide();
       }
     });
arunsignit
  • 209
  • 4
  • 13
0

The reason for this behavior, the mouseup() is binded when I perform the click() on the div. You can check this behavior by adding console.log message in .mouseup event.

So instead try like below.

$('.quicklinks-rollover').on('click', function (e) {
    $('.quicklinks').toggle();
    e.stopImmediatePropagation();
});

$(document).click(function (e) {
    var container = $(".quicklinks");
    console.log(container.has(e.target).length);
    if (container.has(e.target).length === 0) {
        container.hide();
    }
});

Working Fiddle

Praveen
  • 55,303
  • 33
  • 133
  • 164