CSS / jQuery中适用于移动(触摸)设备的下拉菜单

15
我已经阅读了许多关于此主题的话题,即移动设备友好的下拉菜单。 许多时候,在下拉菜单上采用非悬停动作是最佳选择。 有一些解决方法,其中之一是下拉项目的主超链接应链接到一个哈希标记。
这使其在移动设备上运行正常,但对于普通桌面用户来说,这可能会令人困惑。 因此,解决方案是为桌面用户提供普通下拉菜单,其中第一个超链接也链接到页面。 对于移动用户,点击项目将打开下拉菜单,但在主项目上再次点击将打开相应的页面。
我见过以下网站,不知何故它们的菜单正好与此相同: http://www.hgtv.com/ 您可以在平板电脑上查看并单击主菜单,再次轻拍该项目,您将了解我的意思。
但是我如何找到或下载自己网站的相同设置呢?
提前致谢。

你尝试过“查看源代码”吗?你尝试了什么,它又是如何失败的? - Reinstate Monica Cellio
4个回答

20

这是我成功实现的:

function isTouchDevice(){
    return typeof window.ontouchstart !== 'undefined';
}

jQuery(document).ready(function(){
    /* If mobile browser, prevent click on parent nav item from redirecting to URL */
    if(isTouchDevice()) {
        // 1st click, add "clicked" class, preventing the location change. 2nd click will go through.
        jQuery("#menu-main-menu > li > a").click(function(event) {
            // Perform a reset - Remove the "clicked" class on all other menu items
            jQuery("#menu-main-menu > li > a").not(this).removeClass("clicked");
            jQuery(this).toggleClass("clicked");
            if (jQuery(this).hasClass("clicked")) {
                event.preventDefault();
            }
        });
    }
});

我在我的WordPress网站上使用这个功能。在桌面浏览器(非触摸浏览器)上,当点击主菜单项时,它将直接跳转到链接的位置。当悬停时,它将显示下拉菜单。

对于移动设备(触摸浏览器),当点击主菜单项时,它将展开下拉菜单,并且如果再次点击,则会跳转到新的位置。我还添加了一行“重置”代码来使这部分功能正常工作:如果您先点击第一个主菜单项(展开下拉菜单),然后点击第二个主菜单项(展开第二个下拉菜单),然后再次点击第一个主菜单项,它仍然会像下拉菜单一样工作,直到再次点击。没有这行代码,它就会直接跳转到新位置。


1
谢谢!正是我所需要的! - MegaBubbletea
完美运作,正是我所需要的,谢谢! - Robby Cowell

4
这里有一种设备无关的技术(不确定我对此多少信任特征检测..许多现代浏览器即使界面是鼠标,也会报告支持触摸事件),我用它来使悬停菜单在触摸屏上按预期工作(即,在我们只想要第一次点击触发悬停时,防止触摸事件过早“点击”顶部菜单链接)。
诀窍在于认识到触摸悬停+点击事件将会紧接着发生。也就是说,悬停事件将几乎立即被点击事件跟随。我们可以检测到这一点,并防止点击通过...只有在自悬停事件以来经过了一定的时间阈值后,才允许点击触发。
在桌面上测试时,我无论如何都无法让悬停和点击之间的经过时间小于约150毫秒。当在iPad(第四代)上测试时,悬停和点击之间的经过时间始终约为7-8毫秒。所以我选择了50毫秒的阈值时间来允许点击。我编写的jQuery函数如下(假定使用标准嵌套列表CSS悬停菜单):
  function initNav(){
    // make drop-downs work properly with touchscreens by preventing instant hover-click
    $( some_selector_for_your_top_level_list_items ).each(function(){
      var li = $(this);
      li.mouseover(function(){
        // store time of hover event
        li.data( 'hoverTime', new Date().getTime() );
      });
      li.children('a').click(function(){
        // only allow click if at least 50ms has elapsed since hover
        return ( new Date().getTime() - li.data('hoverTime') ) > 50;
      });
    });
  }

到目前为止,它的运行非常顺畅。对于速度较慢的设备来说,50毫秒可能太低了。

对于非JS用户,您仍将拥有默认的CSS悬停行为作为备选方案。

希望这能帮助人们,因为我找不到一个好的即插即用解决方案,而不涉及可疑的功能检测和/或使用JS重写CSS悬停行为。


我花了一些时间寻找各种解决方案,但似乎没有一个干净可靠的。你的解决方案只需要很短的代码片段就能完美运行。非常感谢您的发布! - crdunst
防止悬停是什么意思?在触摸屏上,由于没有光标,所以不可能“悬停”任何东西,对吗? - rockyraw
@rockyraw 我不知道我在哪里使用了“防止悬停”的短语?这段代码防止了CLICK事件的传递。话虽如此,触摸屏浏览器确实会在点击事件之前立即生成一个“虚假”的悬停事件,而这段代码正是利用这种差异来检测鼠标和触摸屏使用之间的时间差异。 - Brian

2
你需要处理多个事件才能在移动和桌面浏览器中实现该功能。
如果你看一下这个例子菜单,你需要悬停才能展开,而在移动设备上,你需要点击/触摸来展开。
我会尝试通过在桌面端使用“悬停”监听器,而在移动端使用“触摸”事件监听器来实现这个功能。
为了做到这一点,你需要向jQuery添加一个自定义事件,比如“触摸”。请参考下面的文章了解如何实现: 如何在iPad的Safari浏览器中使用jQuery识别触摸事件?

谢谢您的回复PJH,我会尽快查看。 - John

0

链接损坏了。 - Rahul Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接