悬停菜单在触摸设备上不起作用,因为 link 被触发
Hover menu is not working on touch-device because link gets triggered
响应式网站上的菜单出现以下问题:
我创建了一个 html 菜单,其中包含 ul
/li
-结构,其中包含 link 作为类别名称
<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。
在桌面上一切正常。问题是,一旦我使用 links 作为类别名称(我需要这样做),它就无法在触摸设备(例如 smartphones/tablets)上工作。
有什么方法可以制作一个菜单,该菜单可以在桌面上使用悬停,并且在使用 links 作为类别名称时仍然可以在触摸设备上使用?
我对使用JavaScript 或jQuery 来解决这个问题没有任何问题。通常我使用的是响应式设计,带有用于智能手机或其他移动设备的额外菜单。因此我使用 @media screen
。遗憾的是,这不适用于所有触摸设备,例如更大的平板电脑,如某些 iPad 或 Microsoft Surface。
感谢您的回答和提示。
编辑:
问题是 <a href>
link 总是被触发,所以当我点击一个类别时菜单不会打开。
我现在还在 JSFiddle
中的类别名称中添加了 links
cursor: pointer
这解决了移动设备上悬停的大部分问题。
顺便说一下 - 你的 fiddle 在我的 Android 设备(华为荣耀 4C)上运行良好。
@edit:添加光标:指针打开
<ul>
元素
无论您在做什么,都应该在触摸设备上运行。
但这是使用 jQuery.
的另一种方法
$('li').click(function(e){
$(this).children('ul').toggle();
e.stopPropagation();
});
运行看下面的代码片段。我在悬停显示 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>
双击 touch-devices
的解决方法
我现在通过添加以下内容找到了解决我的问题的方法 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;
}
现在,第一次单击触摸设备会打开子菜单,而双击会运行 link 的默认操作。
我已经在 android 智能手机和平板电脑以及 iphone 和 ipad 上测试了这个解决方案。我还没有机会在触摸笔记本电脑或 Microsoft Surface 上对其进行测试。如果有人有:随时写评论
或者你也可以在这里试试:
$(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="whosebug.com">maincat1</a>
<ul>
<li>
<a href="whosebug.com">subcat1.1</a>
<ul>
<li>
subcat1.1.1
</li>
<li>
subcat1.1.2
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="whosebug.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>
您可以尝试使用 superfish
它适用于我的悬停菜单。
响应式网站上的菜单出现以下问题:
我创建了一个 html 菜单,其中包含 ul
/li
-结构,其中包含 link 作为类别名称
<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。
在桌面上一切正常。问题是,一旦我使用 links 作为类别名称(我需要这样做),它就无法在触摸设备(例如 smartphones/tablets)上工作。
有什么方法可以制作一个菜单,该菜单可以在桌面上使用悬停,并且在使用 links 作为类别名称时仍然可以在触摸设备上使用?
我对使用JavaScript 或jQuery 来解决这个问题没有任何问题。通常我使用的是响应式设计,带有用于智能手机或其他移动设备的额外菜单。因此我使用 @media screen
。遗憾的是,这不适用于所有触摸设备,例如更大的平板电脑,如某些 iPad 或 Microsoft Surface。
感谢您的回答和提示。
编辑:
问题是 <a href>
link 总是被触发,所以当我点击一个类别时菜单不会打开。
我现在还在 JSFiddle
cursor: pointer
这解决了移动设备上悬停的大部分问题。
顺便说一下 - 你的 fiddle 在我的 Android 设备(华为荣耀 4C)上运行良好。
@edit:添加光标:指针打开
<ul>
元素
无论您在做什么,都应该在触摸设备上运行。 但这是使用 jQuery.
的另一种方法$('li').click(function(e){
$(this).children('ul').toggle();
e.stopPropagation();
});
运行看下面的代码片段。我在悬停显示 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>
双击 touch-devices
的解决方法我现在通过添加以下内容找到了解决我的问题的方法 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;
}
现在,第一次单击触摸设备会打开子菜单,而双击会运行 link 的默认操作。
我已经在 android 智能手机和平板电脑以及 iphone 和 ipad 上测试了这个解决方案。我还没有机会在触摸笔记本电脑或 Microsoft Surface 上对其进行测试。如果有人有:随时写评论
或者你也可以在这里试试:
$(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="whosebug.com">maincat1</a>
<ul>
<li>
<a href="whosebug.com">subcat1.1</a>
<ul>
<li>
subcat1.1.1
</li>
<li>
subcat1.1.2
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="whosebug.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>
您可以尝试使用 superfish
它适用于我的悬停菜单。