I\'ve got the following problem with a menu on a responive website:
I created a html menu which has ul
/li
-structure which contains links as cat
You can try using superfish
It worked for me for my hover menu.
Whatever you are doing should work on touch devices. But here is another way to do it using jQuery.
$('li').click(function(e){
$(this).children('ul').toggle();
e.stopPropagation();
});
Run the following code snippet to see. I have commented css property on hover display none so that you can have better understanding of jQuery code. Uncommenting it will also work fine.
$('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>
Workaround with doubleclick for touch-devices
I now found a solution for my problem by adding the following JavaScript
The idea of how to dectect if the device is a touch device is based on this answer.
$(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');
}
});
});
And the following css
.active > ul >li{
display:block;
}
Now the first click of a touch device opens the submenu while a doubleclick runs the default action of the link.
I have tested this solution on an android smartphone & tablet and also on iphone & ipad. I havn't had the possibility to test it on a touchlaptop or microsoft surface yet. If anyone has: feel free to write a comment
Here's an example JsFiddle
Or you can also try it out here:
$(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="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>
cursor: pointer
This fixes most of the problems with hover on mobiles.
By the way - your fiddle works fine on my Android device (Huawei Honor 4C).
@edit: add cursor: pointer on
<ul>
element