我在支持指针和触摸事件的设备上遇到了 mouseleave 和 hover 问题。这些设备包括带有鼠标和触摸屏的笔记本电脑。
我基本上只是想禁用 mouseleave 和悬停,但问题是它是支持两者的设备,我找不到正确解释这一点的文章,而且没有标准。
我查看了以下链接:
Disable hover effects on mobile browsers
How to remove/ignore :hover css style on touch devices
jquery preventing hover function on touch
jQuery mouseleave for touch screen / tablets
Disable hover effects on mobile browsers
我们使用 DNN (DotNetNuke) 作为内容管理系统。我知道您可以使用 token 和 DDR 菜单构建自定义菜单,但这对于我想要实现的目标来说太复杂了。
我的简单方法是根据从我们的 ERP 数据库获取的数据构建子菜单,并在您将鼠标悬停在 DNN 页面链接上时显示该子菜单,该链接已使用 jQuery 匹配的某个名称“禁用”。
在桌面设备上一切正常。 它还可以与使用 Chrome 的触摸和指针设备配合使用。
我在平板电脑设备上使用 Edge 时遇到触摸和指针事件问题。当您点击“类别”时,会触发 onmouseleave ,这将导致子菜单关闭。当您点击“类别”菜单时,它会触发悬停事件。
更困难的是子菜单不是父菜单的直接子菜单,因此使用 CSS 选择器并不总是那么容易。目前,我将模块放置在菜单下方,以便它至少非常接近,以便我可以使用绝对和相对定位来使子菜单直接显示在链接下方。在这里,您会注意到我在一个 mouseleave 事件上添加了一个超时函数,以允许某人在鼠标离开悬停事件时导航到子菜单。
这是菜单的屏幕截图。它包含可以显示的子类别,但我只想让主菜单在支持触摸和点事件的设备上正确显示。
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;
}
JQUERY
$(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");
}
});
});
最佳答案
他是解决这个问题的更好方法。我监听了clicks
mouseevents
和touchevents
。因此希望可以在任何设备上工作。不过我没有在 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>
关于jquery - 如何在支持触摸和指针事件的设备上处理触摸事件,并且菜单中的子项不是父菜单的子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60727322/