Search code examples
jqueryhyperlinknavigationhovertablet

jQuery tablet hover on top-level linked menu item


I have a list-item header navigation for website, nothing crazy. But the top-level link also has a hover state that opens the sub-menu, and I can't figure out how to get it to work right on a tablet.

When I simply use a jQuery hover script, the top-level nav item clicks through without opening the submenu first.

When I try to add touchstart code, the menu opens but none of the links click through on a tablet, the top-level or the submenu. I click on a link and the only thing that happens is the menu closes.

Ideally, the first tablet click on top-level menu item would open the submenu and a second click on top-level menu item would act as a link to go to the next webpage (as would first clicks on submenu items when submenu is open). Not sure how menu would be closed if a user didn't want to follow a link but just wanted to see submenu options open.

here's my HTML, with some extraneous things stripped out...

<div id="header-nav">
<ul>
<li><a href="webpage1.html">Webpage 1</a></li>
<li><a href="webpage2.html">Webpage 2</a>
    <ul>
        <li><a href="webpage2a.html">Webpage 2a</a></li>
        <li><a href="webpage2b.html">Webpage 2b</a></li>
        <li><a href="webpage2c.html">Webpage 2c</a></li>
        <li><a href="webpage2d.html">Webpage 2d</a></li>
    </ul>
</li>
</ul>
</div>

basic CSS...

#header-nav ul {
    display: inline-block;
    margin: 0 auto;
    padding: 0;
    list-style: none;
}
#header-nav ul li ul {
    display: none;
    background: #fff;
}
#header-nav ul li.active ul {
    display: block;
    position: absolute;
    z-index: 15;
    top: 42px;
    left: 0;
}

and JS, with touchstart scripting...

$('#header-nav ul li').hover(function() {
    $(this).siblings().removeClass('active');
    $(this).addClass('active');
},
  function() {
    $(this).removeClass('active');
});
$('#header-nav ul li').on('touchstart', function(e) {
    'use strict'; 
    var listItem = $(this); 
    if (listItem.hasClass('active')) {
        $(listItem).removeClass('active');
        return true;
    } else {
        listItem.addClass('active');
        $('#header-nav ul li').not(this).removeClass('active');
        e.preventDefault();
        return false; 
    }
});
$('body').on('touchstart', function(e) {
    'use strict'; 
    //var listItem = $(this); 
    if ($('#header-nav ul li').hasClass('active')) {
        $('#header-nav ul li').removeClass('active');
        return true;
    }
});

I've tried it with both of the touchstart functions, and with one or the other, and with none but just the first hover function. I either get a click on first touch of top-level menu item, or no clicks at all other than opening the menu.

alternately, I have this as my hover function which creates a delay on mouseout, but it does't seem to matter which version I use...

var hoverTimeout;
$('#header-nav ul li').hover(function() {
    clearTimeout(hoverTimeout);
    $(this).siblings().removeClass('active');
    $(this).addClass('active');
},
  function() {
    var $self = $(this);
    hoverTimeout = setTimeout(function() {
        $self.removeClass('active');
    }, 500);
});

any and all help much appreciated! I'm stumped on this, probably misunderstanding some simple thing.


Solution

  • Check this out http://osvaldas.info/drop-down-navigation-responsive-and-touch-friendly Just ignore the responsive part, the plugin he provides looks like it solves your problem.