css / jquery 中的移动(触摸)设备友好下拉菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11850466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:59:37  来源:igfitidea点击:

Mobile (touch) device friendly drop down menu in css / jquery

jquerycssipadmobiledrop-down-menu

提问by John

I have been reading many topics on this subject, a drop down menu which is friendly on mobile devices. Many times it is considered best to have a non-hover action on the drop down menu. There are workarounds, with one being that the main hyperlink for the drop down item should link to a hashtag.

我一直在阅读有关此主题的许多主题,这是一个在移动设备上友好的下拉菜单。很多时候,最好在下拉菜单上进行非悬停操作。有一些解决方法,其中一个是下拉项的主要超链接应该链接到一个主题标签。

This makes it work on mobile devices but for the normal desktop user, this would be confusing. So the solution would be to have a normal drop down menu for desktop users in which the first hyperlink also links to a page. For mobile users, the tap on an item will open the drop down menu, but a second tap on the main item will open the corresponding page.

这使得它可以在移动设备上运行,但对于普通的桌面用户来说,这会令人困惑。所以解决方案是为桌面用户提供一个普通的下拉菜单,其中第一个超链接也链接到一个页面。对于移动用户,点击一个项目将打开下拉菜单,但第二次点击主项目将打开相应的页面。

I have seen the following site and somehow their menu works exactly like that: http://www.hgtv.com/You can view this on a tablet and click on the main menu, tap that item again and you will know what i mean.

我看过以下网站,不知何故他们的菜单就像那样:http: //www.hgtv.com/你可以在平板电脑上查看这个,然后点击主菜单,再次点击那个项目,你就会明白我的意思.

But how can i find or download the exact similar setup for my own site?

但是我怎样才能为我自己的网站找到或下载完全相似的设置呢?

Thanks in advance

提前致谢

采纳答案by PJH

You are going to have to handle multiple events to get that functionality in both mobile and desktop browsers.

您将必须处理多个事件才能在移动和桌面浏览器中获得该功能。

If you look at that example menu you hover to expand whereas on mobile you want a click/touch to expand.

如果您查看该示例菜单,您可以将鼠标悬停以展开,而在移动设备上,您需要单击/触摸来展开。

One way I would try to accomplish this would be to have the 'hover' listener for desktop but use a 'touch' event listener for mobile.

我尝试实现此目的的一种方法是为桌面使用“悬停”侦听器,但为移动设备使用“触摸”事件侦听器。

To do this you will have to add a custom event such as 'touch' to jQuery. See the post below for a way to do that:

为此,您必须向 jQuery 添加一个自定义事件,例如“触摸”。请参阅下面的帖子以了解如何做到这一点:

How to recognize touch events using jQuery in Safari for iPad? Is it possible?

如何在 iPad 的 Safari 中使用 jQuery 识别触摸事件?是否可以?

回答by Jeremy

Here's what I got working:

这是我的工作:

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();
            }
        });
    }
});

I'm using this for my WordPress site. On desktop browsers (non-touch browsers), when the main menu item is clicked, it will go straight to the link's location. When hovered, it will show the dropdown.

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

For mobile (touch browsers), when the main menu item is touched, it will expand the dropdown, and if clicked again it will go to the new location. I also added a "reset" line of code to get this part working: if you touch the first main menu item (expanding the dropdown), then touch the second main menu item (expanding the 2nd dropdown), then touch the first main menu item again, it will still behave as a dropdown until clicked again. Without this line, it would just proceed straight to the new location.

对于手机(触摸浏览器),当主菜单项被触摸时,它会展开下拉菜单,如果再次点击它会转到新位置。我还添加了一行“重置”代码以使这部分工作:如果您触摸第一个主菜单项(展开下拉列表),然后触摸第二个主菜单项(展开第二个下拉列表),然后触摸第一个主菜单再次单击项目,它仍将表现为下拉菜单,直到再次单击。如果没有这条线,它将直接前往新位置。

回答by Brian

Here is a device-agnostic technique (not sure how much I trust feature detection for this.. many modern browsers report support for touch events even if the interface is mouse) I used to make hover menus work on touchscreens as expected (ie, prevent the touch event from prematurely "clicking" the top menu link when we just want the first click to trigger a hover).

这是一种与设备无关的技术(不确定我对此有多信任。许多现代浏览器报告支持触摸事件,即使界面是鼠标)我曾经使悬停菜单按预期在触摸屏上工作(即防止当我们只想第一次点击触发悬停时,过早“点击”顶部菜单链接的触摸事件)。

The trick is to recognize that a touch hover+click event will happen right on top of each other.. ie the hover event will be followed almost immediately by the click event. We can detect this and prevent the click from going through... only allowing the click to trigger if a certain threshold of time has elapsed since the hover event.

诀窍是认识到触摸悬停+单击事件将发生在彼此的正上方..即悬停事件几乎立即跟随单击事件。我们可以检测到这一点并防止点击通过...只允许在自悬停事件后经过特定时间阈值时触发点击。

When testing on a desktop, I was never able to get the elapsed time faster than about 150ms between hover and click no matter how fast I clicked. When testing on on an iPad (4th gen) the elapsed time between hover & click was always around 7 - 8 ms. So I chose a threshold time of 50ms to allow clicking. The jQuery function I wrote is as follows (this assumes a standard nested-list CSS hover menu):

在桌面上进行测试时,无论我点击多快,我都无法让悬停和点击之间的运行时间快于大约 150 毫秒。在 iPad(第 4 代)上进行测试时,悬停和单击之间经过的时间始终约为 7 - 8 毫秒。所以我选择了 50ms 的阈值时间来允许点击。我编写的 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;
      });
    });
  }

Working like a charm so far. It's possible 50ms might be too low for much slower devices.

到目前为止,工作就像一个魅力。对于速度较慢的设备来说,50ms 可能太低了。

For non-JS you will still have the default CSS hover behaviour as fallback.

对于非 JS,您仍将使用默认的 CSS 悬停行为作为后备​​。

Hope this helps people, as I couldn't find a good drop-in solution that didn't involve questionable feature detection and/or rewriting your CSS hover behaviour using JS.

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

回答by zar

Try this one: http://suanaikyeo.com/blog/make_dropdown/

试试这个:http: //suanaikyeo.com/blog/make_dropdown/

I already try it and it's working for both hover and click event..

我已经尝试过了,它适用于悬停和点击事件..