悬停菜单无法在触摸设备上运行,因为链接被触发

问题描述 投票:2回答:3

我在响应式网站上的菜单中遇到以下问题:

我创建了一个html菜单,其中包含ul / li-structure,其中包含链接作为类别名称

<ul>
    <li>
       <a href="linkToCat">maincat1</a>
        <ul>
            <li>
                <a href="linkToCat">subcat1.1</a>
                <ul>
                    //deeper category stucture
                </ul>
            </li>
        </ul>
    </li>
    <li>
       <a href="linkToCat">maincat2</a>
        <ul>
            <li>
                <a href="linkToCat">subcat2.1</a>
            </li>
            <li>
                <a href="linkToCat">subcat2.2</a>
            </li>
        </ul>
    </li>
</ul>
<style>
    li > ul {
        display:none;
    } 

    li:hover > ul {
        display:block;
    } 
</style>

我只在开头显示maincats,并且在悬停时打开子键,如此JSFiddle所示。

一切都在桌面上正常工作。问题是,只要我使用链接作为类别的名称(我需要这样做),它就无法在触摸设备(例如智能手机/平板电脑)上工作。

有没有办法制作一个可以悬停在桌面上的菜单,当使用链接作为类别名时,它仍然可以在触摸设备上使用?

我没有使用JavaScript或jQuery来解决这个问题。通常情况下,我正在使用响应式设计,并为智能手机或其他移动设备提供额外菜单。因此我使用@media screen。遗憾的是,这并不适用于所有触摸设备,例如更大的平板电脑,如某些iPad或微软表面。

谢谢你的答案和提示。

编辑:问题是<a href>链接总是得到triggert,因此当我点击一个类别时菜单不会打开。我现在还添加了JSFiddle中类别名称的链接

jquery html menu hover touch
3个回答
2
投票

为触摸设备双击的解决方法

我现在通过添加以下JavaScript找到了解决我问题的方法

如何检测设备是否是触摸设备的想法是基于this的答案。

$(document).ready(function(){
    //added for surface
    window.USER_IS_TOUCHING = false;
    window.addEventListener('touchstart', function onFirstTouch() {
        window.USER_IS_TOUCHING = true;
        // we only need to know once that a human touched the screen, so we can stop listening now
        window.removeEventListener('touchstart', onFirstTouch, false);
    }, false);

    function is_touch_device() {
      return 'ontouchstart' in window        // works on most browsers 
          || navigator.maxTouchPoints;       // works on IE10/11 and Surface
    };
    $('ul > li > a').click(function(e){
        var target = $(e.target);
        var parent = target.parent(); // the li
        if(is_touch_device() || window.USER_IS_TOUCHING){
            if(target.hasClass("active")){
                //run default action of the link
            }
            else{
                e.preventDefault();
                //remove class active from all links
                $('ul > li > a.active').removeClass('active');
                //set class active to current link
                target.addClass("active");
                parent.addClass("active");
            }
        }
    });
    $('ul > li').click(function(e){
        //remove class active from all links if li was clicked
        if (e.target == this){
            $(".active").removeClass('active');
        }
    });
});

以下css

.active > ul >li{
    display:block;
}

现在,第一次点击触摸设备会打开子菜单,而双击则会运行链接的默认操作。

我已经在Android智能手机和平板电脑以及iphone和ipad上测试了这个解决方案。我还没有可能在touchlaptop或microsoft表面测试它。如果有人:随时写评论

Here's an example JsFiddle

或者您也可以在这里试试:

$(document).ready(function(){
	window.USER_IS_TOUCHING = false;
	window.addEventListener('touchstart', function onFirstTouch() {
    window.USER_IS_TOUCHING = true;
	 	// we only need to know once that a human touched the screen, so we can stop listening now
  	window.removeEventListener('touchstart', onFirstTouch, false);
	}, false);

  function is_touch_device() {
    return 'ontouchstart' in window        // works on most browsers 
        || navigator.maxTouchPoints;       // works on IE10/11 and Surface
  };
  $('ul > li > a').click(function(e){
      var target = $(e.target);
      var parent = target.parent(); // the li
      if(is_touch_device() || window.USER_IS_TOUCHING){
          if(target.hasClass("active")){
              //run default action of the link
          }
          else{
              e.preventDefault();
              //remove class active from all links
              $('ul > li > a.active').removeClass('active');
              //set class active to current link
              target.addClass("active");
              parent.addClass("active");
          }
      }
  });
  $('ul > li').click(function(e){
    //remove class active from all links if li was clicked
    if (e.target == this){
      $(".active").removeClass('active');
    }
  });
});
li > ul {
  display:none;
} 

li:hover > ul {
  display:block;
} 

.active > ul >li{
  display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
        <li>
            <a href="stackoverflow.com">maincat1</a>
            <ul>
                <li>
                    <a href="stackoverflow.com">subcat1.1</a>
                    <ul>
                        <li>
                            subcat1.1.1
                        </li>
                        <li>
                            subcat1.1.2
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>
            <a href="stackoverflow.com"> maincat2</a>
            <ul>
                <li>
                    subcat2.1
                </li>
                <li>
                    subcat2.2
                </li>
                <li>
                    subcat2.3
                     <ul>
                        <li>
                            subcat2.3.1
                        </li>
                        <li>
                            subcat2.3.2
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>

1
投票
cursor: pointer

这可以解决悬停在手机上的大部分问题。

顺便说一句 - 你的小提琴在我的Android设备(华为Honor 4C)上运行良好。

@edit:在<ul>元素上添加cursor:pointer


1
投票

无论你做什么,都应该使用触摸设备。但是这是另一种使用jQuery的方法。

$('li').click(function(e){
    $(this).children('ul').toggle();
    e.stopPropagation();
});

运行以下代码段以查看。我在悬停显示无评论css属性,以便您可以更好地理解jQuery代码。取消注释它也可以正常工作。

$('li').click(function(e){
	$(this).children('ul').toggle();
  e.stopPropagation();
});
li > ul {
  display:none;
} 

/*li:hover > ul {
  display:block;
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>
      maincat1
      <ul>
          <li>
              subcat1.1
              <ul>
                  <li>
                      subcat1.1.1
                  </li>
                  <li>
                      subcat1.1.2
                  </li>
              </ul>
          </li>
      </ul>
  </li>
  <li>
      maincat2
      <ul>
          <li>
              subcat2.1
          </li>
          <li>
              subcat2.2
          </li>
          <li>
              subcat2.3
               <ul>
                  <li>
                      subcat2.3.1
                  </li>
                  <li>
                      subcat2.3.2
                  </li>
              </ul>
          </li>
      </ul>
  </li>
</ul>
© www.soinside.com 2019 - 2024. All rights reserved.