悬停菜单在触摸设备上不起作用,因为链接被触发
Posted
技术标签:
【中文标题】悬停菜单在触摸设备上不起作用,因为链接被触发【英文标题】:Hover menu is not working on touch-device because link gets triggered 【发布时间】:2017-06-23 07:22:23 【问题描述】:我在响应式网站上的菜单遇到以下问题:
我创建了一个 html 菜单,其中包含 ul
/li
-结构,其中包含作为类别名称的链接
<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>
我只在开头显示主猫,子猫在悬停时打开,如JSFiddle 所示。
在桌面上一切正常。问题是,一旦我使用链接作为类别名称(我需要这样做),它就不适用于触摸设备(例如智能手机/平板电脑)。
有没有什么方法可以制作一个可以在桌面上悬停的菜单,并且在使用链接作为类别名称时仍然可以在触摸设备上使用?
我对使用 javascript 或 jQuery 来解决这个问题没有任何问题。通常我使用响应式设计和智能手机或其他移动设备的额外菜单。因此我使用@media screen
。遗憾的是,这不适用于所有触摸设备,例如一些 iPad 或 Microsoft Surface 等更大的平板电脑。
感谢您的回答和提示。
编辑:
问题是<a href>
链接总是被触发,所以当我点击一个类别时菜单不会打开。
我现在还在JSFiddle 中添加了指向类别名称的链接
【问题讨论】:
我认为touch mobile中没有这样的悬停事件。 @Rajesh Baskaran 是的,遗憾的是我找不到一个.. 唯一对我有用的是双击的解决方法 您可以将悬停条件设为默认值。例如:如果悬停时有背景颜色,则只需将媒体查询编写为元素 backgroundcolor:none 【参考方案1】:触摸设备双击的解决方法
我现在通过添加以下 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 isTouchDevice()
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(isTouchDevice() || 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;
现在第一次点击触摸设备会打开子菜单,而双击则会运行链接的默认操作。
我已经在安卓智能手机和平板电脑以及 iPhone 和 iPad 上测试了这个解决方案。我还没有机会在触摸笔记本电脑或微软表面上测试它。如果有人有:请随时发表评论
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 isTouchDevice()
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(isTouchDevice() || 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="***.com">maincat1</a>
<ul>
<li>
<a href="***.com">subcat1.1</a>
<ul>
<li>
subcat1.1.1
</li>
<li>
subcat1.1.2
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="***.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>
【讨论】:
菜单在触摸时不会展开。它转到 URL。这发生在笔记本电脑和平板电脑上。【参考方案2】:无论您做什么,都应该在触控设备上工作。 但这里有另一种使用 jQuery 的方法。
$('li').click(function(e)
$(this).children('ul').toggle();
e.stopPropagation();
);
运行以下代码sn -p 看看。我在 hover display none 上注释了 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>
【讨论】:
【参考方案3】:cursor: pointer
这解决了在手机上悬停的大部分问题。
顺便说一句 - 你的小提琴在我的 android 设备(华为荣耀 4C)上运行良好。
@edit: 添加光标: 指针
<ul>
元素
【讨论】:
是否有任何支持文档说明为什么或如何解决问题?【参考方案4】:您可以尝试使用superfish
它适用于我的悬停菜单。
【讨论】:
以上是关于悬停菜单在触摸设备上不起作用,因为链接被触发的主要内容,如果未能解决你的问题,请参考以下文章