Making Dropdowns Work on Touch Devices like Tablets
I swear this used to be default functionality, but lately on my iPad, some websites–when viewed on tablets–don’t allow you to click a top-level navigation element to show the dropdown. Instead, they just jump to whatever the URL of the top level navigation’s `<a>` href is.
If you’re running into this, here’s how to fix it with some jQuery. First, the code below assumes you have navigation HTML like so:
<ul class="nav">
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a>
<ul class="sub-menu">
<li><a href="/company/">Company</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</li>
</ul>
That’s a pretty standard setup, and should work well with many a WordPress default navigation.
Here’s the jQuery:
function is_touch_device() {
return 'ontouchstart' in window // for standard browsers
|| 'onmsgesturechange' in window; // for IE10
}
if (is_touch_device()) {
$('ul.nav > li').each(function(){
if ( $(this).children('ul.sub-menu').length > 0 ) {
$(this).addClass('touch-top-level');
}
});
$( "li.touch-top-level > a" ).one( "click", function(e) {
e.preventDefault();
});
};
Let’s review quickly for those who want to know what’s actually happening.
function is_touch_device()
creates a function that simply tests for touch events.
if (is_touch_device()) {
runs the function. If the browser indicates that yes, it does have touch functionality, this returns true and the rest of the code is executed.
$('ul.nav > li').each(function(){
Here we check for all li
elements that belong immediately to the ul.nav
– which is what >
does in this line. So it won’t detect an li
in our .sub-menu
lists, since those aren’t “immediately” children of ul.nav
.
if ( $(this).children('ul.sub-menu').length > 0 ) {
checks to see if the li
we just checked has a sub-menu, and if so, we add a CSS class of touch-top-level
via $(this).addClass('touch-top-level');
to make it easier to work with.
$( "li.touch-top-level > a" ).one( "click", function(e) {
– there the .one
tells jQuery to only do this action once per element it applies to.
e.preventDefault();
this basically says “Don’t follow the link” in this case.
If they click it a second time, though, it will follow the link since we had set one
.
Have fun!
Up Next: How to Get aggregateRating Schema / Google Structured Data for Woocommerce Reviews