【问题标题】:Menu open by hover on desktop, click on mobile将鼠标悬停在桌面上打开菜单,单击移动设备
【发布时间】:2015-10-21 21:31:15
【问题描述】:

我正在尝试创建一个菜单按钮,当它悬停时,会在桌面上显示一组下拉链接。但是,显然用户无法将鼠标悬停在手机等设备上,因此一直在尝试研究如何让按钮在点击时也显示菜单。

到目前为止,我已经设法使用 jquery 在鼠标进入和离开时添加和删除 .show-nav 类。我尝试添加以下代码块,但它显然也会影响桌面,如果有人单击按钮,这会使菜单有点混乱(因为该类应用于悬停,然后使用单击永久添加和删除)。

感谢 cesare,除了 iOS 上的 Chrome 之外,一切都正常运行。 djtwigg 的解决方案适用于 Chrome,但不适用于 safari。是否可以将两种解决方案合并在一起?

<nav>
    <ul>
        <li id="nav-button">
            <a id="nav-click" href="#">Menu <i class="fa fa-bars"></i></a>
            <ul class="sub-nav">
                <li><a href="#">Link1</a></li>
                <li><a href="#">Link2</a></li>
                <li><a href="#">Link3</a></li>
                <li><a href="#">Link4</a></li>
            </ul>
        </li>
    </ul>
</nav>

var flag = false;
container.bind('touchstart', function(){
if (!flag) {
   flag = true;
   setTimeout(function(){ flag = false; }, 260);
   list.toggleClass('show-nav');
}
return false
});

container.hover(function(){
   list.addClass('show-nav');
}, function(){
   list.removeClass('show-nav');    
});
});

【问题讨论】:

  • 请附上代码。
  • 我附上了一个我想要实现的基本版本的小提琴。不过,我会在我的问题中添加更多代码。

标签: javascript jquery mobile menu hover


【解决方案1】:

桌面可以使用“hover”,移动设备可以绑定“touchstart”。

var flag = false;
container.bind('touchstart', function(){
if (!flag) {
   flag = true;
   setTimeout(function(){ flag = false; }, 260);
   list.toggleClass('show-nav');
}
return false
});

container.hover(function(){
   list.addClass('show-nav');
}, function(){
   list.removeClass('show-nav');    
});

试试这个小提琴: https://jsfiddle.net/62cvsvvc/6/

这个解决方案的灵感来自这个问题: How to bind 'touchstart' and 'click' events but not respond to both?

编辑 我检查了我的服务器并正常工作。 我猜这个 iOS 问题与 jsFiddle 环境有关。

请试穿: http://cesare.heliohost.org/test/

【讨论】:

  • 我刚刚试过你的小提琴,不幸的是在桌面上 touchstart 似乎注册为点击,然后反转悬停效果直到再次点击。同样在我的iphone上,我根本无法激活按钮,但不知道为什么。编辑:再看一眼小提琴后,我似乎无法重新创建悬停效果的反转。也许某些东西第一次没有正确加载。不幸的是,我仍然没有在移动设备上采取任何行动。
  • 我已经更新了小提琴jsfiddle.net/62cvsvvc/6,现在回调是分开的以避免一些错误。如果现在完成目标,请尝试。
  • 这对除了 IOS 之外的所有东西都有效。似乎根本没有看到点击正在被拾取。
  • 我猜这个问题与 jsFiddle 环境有关。请在我的服务器上尝试:cesare.heliohost.org/test 如果可以,请接受答案。
  • 这在 safari 中完美运行,但在 Chrome 中无效。你知道为什么会这样吗?
【解决方案2】:

使用touchstart 事件:

$('#nav-button').on('touchstart', function(){
     $('.sub-nav').toggleClass('show-nav');
});

【讨论】:

  • 不幸的是,这似乎不起作用。我相信这是因为浏览器在触摸之前注册了鼠标输入,因此立即删除了类(因为 mouseenter 添加了类)。
【解决方案3】:

可以通过检查事件是触摸还是点击来做到这一点。我找到了一个有用的插件:Gist of plugin

只需检查点击,如果是触摸点击,则切换菜单。使用 preventDefault() 如小提琴所示。通过检查鼠标是否是鼠标而不是触摸来添加或删除 mouseenter 和 mouseleave 上的类。

    // Bind mouse events to links.
  container
    .click(myClickCallback)
    .mouseenter(myMouseenterCallback)
    .mouseleave(myMouseleaveCallback);

  // Click callback.
  function myClickCallback(e) {
    var touchOrMouse = $body.touchOrMouse('get', e);

    // If mouse event has been invoked by touch.
    if (touchOrMouse === 'touch') {
      // Toggle .hovered class.
      list.toggleClass('show-nav');
    }

    // Do not follow the link.
    e.preventDefault();
  }

  // Mouse enter callback.
  function myMouseenterCallback(e) {
    var touchOrMouse = $body.touchOrMouse('get', e);

    // If mouse event has not been invoked by touch.
    if (touchOrMouse === 'mouse') {
      // Add .hovered class.
      list.addClass('show-nav');
    }
  }

  // Mouse leave callback.
  function myMouseleaveCallback(e) {
    var touchOrMouse = $body.touchOrMouse('get', e);

    // If mouse event has not been invoked by touch.
    if (touchOrMouse === 'mouse') {
      // Remove .hovered class.
      list.removeClass('show-nav');
    }
  }

这是一个在 iPhone 上工作的例子:Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-19
    • 2017-08-02
    • 2016-02-25
    • 1970-01-01
    • 2015-06-12
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多