首页 > 解决方案 > 如何处理支持触摸和指针事件的设备上的触摸事件,其菜单包含不是父菜单子项的子项

问题描述

我在支持 Pointer 和 Touch 事件的设备上遇到mouseleavehover问题。这些设备包括带有鼠标和触摸屏的笔记本电脑。

我基本上只是想禁用鼠标离开和悬停,但问题是它是支持两者的设备,我找不到正确解释这一点的文章并且没有标准。

我查看了以下链接:

在移动浏览器上禁用悬停效果

如何删除/忽略:触摸设备上的悬停 CSS 样式

jquery防止触摸悬停功能

用于触摸屏/平板电脑的 jQuery mouseleave

在移动浏览器上禁用悬停效果

我们使用 DNN (DotNetNuke) 作为内容管理系统。我知道您可以使用令牌和 DDR 菜单构建自定义菜单,但这对于我想要实现的目标来说太复杂了。

我的简单方法是从我们的 ERP 数据库中获取的数据构建子菜单,并在您将鼠标悬停在 DNN 页面链接上时显示它,该链接已“禁用”,具有使用 jQuery 匹配的特定名称。

在桌面设备上一切正常。它也适用于使用 Chrome 的触控和指针设备。

我在带有触控和指针事件的平板设备上遇到 Edge 问题。当您点击“类别”时会触发 onmouseleave,这将导致子菜单关闭。当您点击“类别”菜单时,它会触发悬停事件。

更困难的是子菜单不是父菜单的直接子菜单,因此使用 CSS 选择器并不总是那么容易。目前我将模块放在菜单下方,使其至少非常接近,以便我可以使用绝对和相对定位来让子菜单直接显示在链接下方。在这里您会注意到我在一个 mouseleave 事件上添加了一个超时功能,以允许某人在鼠标离开悬停事件时导航到子菜单。

这是菜单的屏幕截图。它包含可以显示的子类别,但我只想让主菜单在支持 Touch 和 Point 事件的设备上正确显示。

在此处输入图像描述

示例 JSFidle 代码

JSFidle: https ://jsfiddle.net/Tig7r/e6k9cfj1/13/

HTML

<nav class="NavMenu">
  <ul class="ul_menu">
  <li class='item'><a href="#"><span>Home</span></a></li>
  <li class='item'><a><span>Categories</span></a></li>
  </ul>
</nav>


<div class="subLevel MegaMenuDiv" id="MegaMenuDiv">
  <div class="custom_megamenu_wrapper">
   <ul class="main-category-list has-children"><li><a href="javascript:void(0)" class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" style="">Accessories</a>
      <ul class="secondary-items">
      <li><a href="https://www.google.com" class="MegaMenu_Child_Link" style="">Accessory Holders</a></li>
      <li><a href="https://www.google.com" class="MegaMenu_Child_Link" style="">Whiteboard Starter Pack</a></li>
   </ul></li>
</ul>
 </div>
</div>

css

.NavMenu{
  width:100%;
  height:40px;
  background-color:red;
  color:white !important;
}

.NavMenu ul li{
  list-style:none;
  display:inline-block;
  padding:10px;
}

.ul_menu li a:link{
  color:white;
}

.ul_menu li a:hover{
  color:black;
}

#MegaMenuDiv{
  background:black;
  color:white;
  position:absolute;
  width:550px;
  display:none;
  min-height:300px;
}

.MegaMenuDiv a:link{
  color:white;
}

.displayHiddenMenu{
  display: block !important;
}

.main-category-list li{
  list-style:none;
}

.secondary-items{
  background: #31383e;
  position: absolute;
  top: 0;
  left: 150px;
  width: calc(80vw - 50%);
  height: auto;
  list-style: none;
  /* padding: 20px; */
  display: none;
  height: 92%;
  overflow-y: auto;
  padding-top: 0px;
  z-index: 1000;
  max-width: 840px;
  padding-top: 13px;
  line-height: 2;
}

.secondary-items a:link, .secondary-items a:visited{
  color:white !important;
}

查询

$(document).ready(function () {

$(".item:contains(Categories)").hover(function () {
        if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {          
        } else {
            console.log('No class, adding class');
            $('.MegaMenuDiv').addClass("displayHiddenMenu");
        }
    }); 

 /* Removes the submenu when the mouse moves away from categories */
 $('.item:contains(Categories)').on("mouseleave", function (event) {
       if ($('.MegaMenuDiv:hover').length > 0) {
       // do nothing
       } else {             
                $('.MegaMenuDiv').removeClass("displayHiddenMenu");
       }
});

$(".item:contains(Categories)").hover(function () {
    if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
      console.log('Item has class');
    } else {
      console.log('No class, adding class');
      $('.MegaMenuDiv').addClass("displayHiddenMenu");
    }
});

  $(".item:contains(Categories)").on("touchstart click", function () {
    if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
      $('.MegaMenuDiv').removeClass("displayHiddenMenu");
    } else {
      $('.MegaMenuDiv').removeClass("displayHiddenMenu");
      $('.MegaMenuDiv').addClass("displayHiddenMenu");
    }
  });

  $('.MegaMenuDiv').on("mouseleave", function () {
    console.log('Mouseleave remove class');
    $('.MegaMenuDiv').removeClass("displayHiddenMenu");
  });

//Code for child menu elements
  $('.MegaMenuLinkMainWithChildren').hover(function () {
        if ($(this).next().hasClass('displayHiddenMenu')) {
                //do nothing
        } else {
            $('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
            $(this).next().addClass('displayHiddenMenu');
        }
});

$('.MegaMenuLinkMainWithChildren').on('touchstart click', function () {
        var secondaryitems = $(this).next();        
        if ($(secondaryitems).hasClass('displayHiddenMenu')) {

        } else {
            $('.MegaMenuLinkMainWithChildren').next().not(secondaryitems).removeClass('displayHiddenMenu');
            $(secondaryitems).addClass("displayHiddenMenu");
        }
});

});

标签: jquerymobiledotnetnuketouch-event

解决方案


他是解决这个问题的更好方法。我有听clicks mouseeventstouchevents。因此希望可以在任何设备上工作。但是我没有在 Edge 上进行测试。希望能帮助到你。

您还可以收听所有.NavMenu .item元素并隐藏.MegaMenuDiv如果它不是类别项目,因为有人可能会不小心悬停类别项目。

// main menu
$(".item:contains(Categories)").on('mouseenter touchstart click', function(e) {
	
	// toggle MegaMenuDiv on click
	e.type == 'click' ? $('.MegaMenuDiv').toggleClass("displayHiddenMenu") : $('.MegaMenuDiv').addClass("displayHiddenMenu");
});

$('#MegaMenuDiv').on('click', function(e){
	if(e.target == $('#MegaMenuDiv').get(0)){
  	$('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
  }
}).on('mouseleave', function(){
  $('#MegaMenuDiv .secondary-items').removeClass('displayHiddenMenu');
	$('#MegaMenuDiv').removeClass("displayHiddenMenu");
});

// MegaMenuLinkMainWithChildren
$(".MegaMenuLinkMainWithChildren").on('mouseenter touchstart click', function() {
	// toggle MegaMenuDiv
  $('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
  $(this).next().addClass('displayHiddenMenu');
});
.NavMenu{
  width:100%;
  height:40px;
  background-color:red;
  color:white !important;
}

.NavMenu ul li{
  list-style:none;
  display:inline-block;
  padding:10px;
}

.ul_menu li a:link{
  color:white;
}

.ul_menu li a:hover{
  color:black;
}

#MegaMenuDiv{
  background:black;
  color:white;
  position:absolute;
  width:550px;
  display:none;
  min-height:300px;
}

.MegaMenuDiv a:link{
  color:white;
}

.displayHiddenMenu{
  display: block !important;
}

.main-category-list li{
  list-style:none;
}

.secondary-items{
  background: #31383e;
  position: absolute;
  top: 0;
  left: 150px;
  width: calc(80vw - 50%);
  height: auto;
  list-style: none;
  /* padding: 20px; */
  display: none;
  height: 92%;
  overflow-y: auto;
  padding-top: 0px;
  z-index: 1000;
  max-width: 840px;
  padding-top: 13px;
  line-height: 2;
}

.secondary-items a:link, .secondary-items a:visited{
  color:white !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<nav class="NavMenu">
    <ul class="ul_menu">
        <li class="item">
            <a href="#">
                <span>
                    Home
                </span>
            </a>
        </li>
        <li class="item">
            <a>
                <span>
                    Categories
                </span>
            </a>
        </li>
    </ul>
</nav>
<div class="subLevel MegaMenuDiv" id="MegaMenuDiv">
    <div class="custom_megamenu_wrapper">
        <ul class="main-category-list has-children">
            <li>
                <a class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" href="javascript:void(0)" style="">
                    Accessories
                </a>
                <ul class="secondary-items">
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Accessory Holders
                        </a>
                    </li>
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Whiteboard Starter Pack
                        </a>
                    </li>
                </ul>
            </li>
            <li>
                <a class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" href="javascript:void(0)" style="">
                    Other
                </a>
                <ul class="secondary-items">
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Accessory
                        </a>
                    </li>
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Starter Pack
                        </a>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</div>


推荐阅读