I have this drop-down menu that drops down on hover normally, but on touch devices, I simply made it so that you can click to open it as well.
The problem is that it seems like the <ul>
that drops down isn't completely in focus or something because I have to click the links twice on my iPhone 4 to make them work.
Here's the code I'm working with:
$(document).ready(function() {
$('.myMenu > li').bind('mouseover', openSubMenu);
$('.myMenu > li').bind('mouseout', closeSubMenu);
$('.myMenu > li').bind('click', toggleSubMenu);
/* Also tried, currently using:
$('.myMenu > li').bind('tap', toggleSubMenu);
*/
function openSubMenu() {
$(this).find('ul').addClass("hovered");
};
function closeSubMenu() {
$(this).find('ul').removeClass("hovered");
};
function toggleSubMenu() {
$(this).find('ul').toggleClass("hovered").focus();
};
});
The .focus()
was the fix I tried adding. It didn't break the code but didn't fix it either. I know there are several things I can do to make it better for touch-devices, but for now, the click method is what I'm sticking with.
By the way:
.hovered{
opacity:1 !important;
visibility: visible !important;
}
The HTML setup is basically <ul>
s inside <ul>
s like you would expect from a drop-down menu. If you for some reason want the markup just say so and I'll add it.
EDIT: Here's the link to the website I'm working on: http://bok-it.underbakke.net
EDIT: Some additional information you might find useful that I noticed just now. The first time I click the link, the CSS on that link acts like it's hovered (as : hover) when I click on the sub-link the first time the main link (the one I first clicked to show the dropdown) loses the state of hover. This is why I think this is a focus issue.
EDIT: The HTML markup as requested:
<ul class="myMenu">
<li><a href="/"><span class="icon-home"></span> Framside</a></li>
<li><a href="#" id="nbutikk"><span class="icon-cart"></span> Butikk</a>
<ul>
<li><a href="/sand"><span class="icon-cart"></span> Sand</a></li>
<li><a href="/sauda"><span class="icon-cart"></span> Sauda</a></li>
<li><a href="http://kontorhandel.no"><span class="icon-cart"></span> Nettbutikk</a></li>
</ul>
</li>
<li><a href="#" id="nit-tjenester"><span class="icon-console"></span> IT Tjenester</a>
<ul>
<li><a href="/driftsavtale"><span class="icon-console"></span> Driftsavtale</a></li>
<li><a href="/asp_vps"><span class="icon-console"></span> ASP & VPS</a></li>
<li><a href="/overvaking"><span class="icon-console"></span> Overvåking</a></li>
<li><a href="/nettverk"><span class="icon-console"></span> Nettverk</a></li>
</ul>
</li>
<li><a href="#" id="nsupport"><span class="icon-info"></span> Support</a>
<ul>
<li><a href="/fjernsupport"><span class="icon-info"></span> Fjernsupport</a></li>
<li><a href="/utskrift_asp"><span class="icon-info"></span> Utskrift ASP</a></li>
<li><a href="/rdp_rycloud"><span class="icon-info"></span> RDP: Rycloud</a></li>
<li><a href="teamviewer_host"><span class="icon-info"></span> TeamViewer Host</a></li>
</ul>
</li>
<li><a href="/kontakt"><span class="icon-mail"></span> Kontakt Oss</a></li>
</ul>
--------------SOLUTION--------------
EDIT: For people that are seeking the solution to this, here's the jQuery that fixed it for me (You should also give @jonsuh an upvote for wipping out the solution):
$(".myMenu li ul li a").on("touchend", function(event) {
window.location.href = $(this).attr("href");
});
Click Start > Settings > Display > Multiple displays > Drag the icon 2 and drag it in front of icon 1, or click icon 2 and then check Make this my main display. Feel free to reach back if you need further assistance.
onclick works fine on touchscreens; I've used it several times and have never had any problem. You could consider using onmousedown instead of onclick. Or use jQuery to detect taps. Why should I use onmousedown instead of onclick? onmousedown is equivalent to ontouchstart on touchdevices, and the equivalent of onmouseup is ontouchend.
It works perfectly except for the fact that touch does not work if it is set up as the second display. For Windows 10 I have to use "Table PC Settings" to assign touch input to secondary monitor. On Windows 11 I cannot find any tools like this. So the touch input is always triggering primary monitor.
the browser may fire both touch events and mouse events in response to the same user input [emphasis mine] the element's touch event handlers should call preventDefault () and no additional mouse events will be dispatched
When you mouseover a link in the submenu, the state of the parent list item changes.
However in iOS, when you click on a link in the submenu, it detects that the parent list item state needs to change, so instead of executing a tap, it's changing the state of the item, which is why it's requiring a second tap. (I hope this makes sense).
To cut to the chase, make sure there isn't a state change in the parent list item. Keep it the same when you hover over it as when you're hovering over the submenu links.
I haven't tested these and it's tough when I'm not working with the code live, but possible solutions could be as follows:
You could do it with jQuery and detecting a touch end, which isn't the best solution, but it should work:
$(".myMenu ul li a").on("touchend", function(event) {
window.location.href = $(this).attr("href");
});
Another is to try to keep the state the same with CSS and it may keep Safari from detecting a change in state. (I removed my CSS answer since it didn't work)
Read this: http://sitr.us/2011/07/28/how-mobile-safari-emulates-mouse-events.html
But if a clickable element also does something on mouseover then tapping on that element will trigger a mouseover event instead of a click. Tapping on the same element again will produce a click event.
If you have a mouseover event, iOS (maybe other OSes) will fire that upon initial click rather than the actual click event. I'd add some alerts to your JS to see which event, exactly, is being called on that initial tap.
Instead of having the click event of Jquery try the tap event like
$('.myMenu > li').bind('tap', toggleSubMenu);
Documentation for Tap
I forget where I found this solution but with jQuery I do something like this and it seems to do the trick:
$(document).ready(function() {
$('a,input').bind('touchend', function() {});
});
I used to use 'touchstart' but 'touchend' seems to be working better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With