1

I've created a mobile dropdown menu for a responsive website, that essentially shows a hidden unordered list when you click on a certain element. It works great, except for the fact that I can't get the blur() function to work, so that when a user clicks anywhere on the page other than inside the menu, it hides the menu. Here's a codepen: http://codepen.io/trevanhetzel/pen/wIrkH

My javascript looks like so:

$(function() {
    var pull = $('#pull');
    menu = $('header ul');

    $(pull).on('click', function(e) {
        e.preventDefault();
        $('.close-menu').toggle();
        $('.mobi-nav span').toggle();
        menu.slideToggle(250);
    });

    $(menu).blur(function() {
        $(this).slideToggle();
    });
});

I've struggled with blur() in the past, so would really like to figure out once and for all how exactly it works, and whether or not I'm using it in the right context here. Thanks!

Trevan Hetzel
  • 1,371
  • 7
  • 21
  • 42
  • 2
    Blur only happens on elements that can gain focus, such as input elements. – Kevin B Apr 12 '13 at 21:16
  • Well therein lies my problem :). Is there another similar function that works for regular block elements when you "click off"? – Trevan Hetzel Apr 12 '13 at 21:18
  • 1
    `$(document).on('click',function(e){ if ( $(e.target).closest('header').length == 0 && e.target.nodeName != 'HEADER' ) $(menu).slideToggle() });` There are a lot of other ways. You may use that solution. It handlers every click on document and check his target. – Novelist Apr 12 '13 at 21:21
  • Holy cow, that was fast! I was just looking at http://stackoverflow.com/questions/1259716/how-to-blur-the-div-element and trying to figure out how to implement something similar, and you hit the head on the nail. Post that as an answer! Thanks :) – Trevan Hetzel Apr 12 '13 at 21:23

1 Answers1

1

You have to watch for clicks yourself. And use $.contains to see if the clicked thing is within your menu:

$(document).click(function (ev) {
    if (ev.target !== menu.get(0) && !$.contains(menu.get(0), ev.target)) {
       menu.slideUp();
    }
});

Just be sure to call ev.stopPropagation() in your toggle click handler to prevent the handler above from immediately closing the menu when the event bubbles up.

Brandon
  • 38,310
  • 8
  • 82
  • 87
  • Thanks for the answer. I can see how this works, but think a little tweaking needs done, which I'm trying to figure out. If you look at my test site: http://test.hetzelcreative.com/hybrid/ and resize your browser way down till the mobile nav appears, you'll notice that clicking on the menu icon immediately toggles down and up the menu. So it's not exactly working, because the menu doesn't stay open until you click out of it like I'm after. Any ideas? – Trevan Hetzel Apr 12 '13 at 21:30
  • Yes. The body click handler is firing after the menu click handler (event bubbling). Only add the body click handler within your menu toggle button click handler (when you are opening the menu). And remove the handler whenever you close the menu. – Brandon Apr 12 '13 at 21:33
  • Okay I realize it's firing after the menu click handler, but putting it before it doesn't solve the issue either. I'm not sure where I'm getting lost at here, but here's how I implemented it: http://codepen.io/trevanhetzel/pen/wIrkH Where would I move the body click handler? – Trevan Hetzel Apr 12 '13 at 21:38
  • Actually the easiest way is to stop the event propagation in your pull event handler. I updated your example (and also bound the click to `document` instead of `body`): http://codepen.io/anon/pen/ipGvA – Brandon Apr 12 '13 at 21:50
  • Cool thanks. That works on desktop, but not my iPhone. Argh... I don't get it lol – Trevan Hetzel Apr 12 '13 at 22:05
  • 1
    @TrevanHetzel, I think iPhone as a mobile devise use an other events. Try to use `touchstart` event. `$(document).on('touchstart click',func...` – Novelist Apr 12 '13 at 22:27
  • Oh, and one more little thing. Some fix. I think you need to reset the menu on blur. So, you may emulate click on the crosshair. `$('.close-menu').trigger('click');` instead of `menu.slideUp()` – Novelist Apr 12 '13 at 22:34