Sounds like a simple problem, but turns out to be quite challenging to solve. For some website I have contents that are only to be shown if a user hovers/focuses a link. The link however has a target itself.
If one of those links is clicked by a touch screen user the browser instantly goes to the href
location. This means the hover contents are never visible!
This is why users which do not have a mouse (or another device to hover like a magic remote control) should see alternative content. But how can I detect this?
$(document).on('click','#my-menu-inner > ul > li > a',function(e) {
if(clientHasInputDeviceSupportingHover()) {
return true;
} else {
e.preventDefault();
$('#for-no-hover-visitors').html('');
$(this).clone().appendTo('#for-no-hover-visitors');
$(this).next().clone().appendTo('#for-no-hover-visitors');
}
});
function clientHasInputDeviceSupportingHover() {
// HOW CAN I DETECT THIS???
if($('#checkhover:checked').length > 0) {
return true;
}
return false;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
#my-menu-inner > ul {
margin:10px;
width:100%;
background-color:yellow;
list-style-type:none;
position:relative;
}
#my-menu-inner > ul > li {
float:left;
margin:20px;
}
#my-menu-inner > ul > li > a {
padding:20px;
border:1px solid black;
display:block;
}
#my-menu-inner > ul > li > div.sub {
position:absolute;
top:calc(100% - 20px);
background-color:red;
padding:40px;
display:none;
left:0;
width:100vw;
}
#my-menu-inner > ul > li a:hover + div.sub, #my-menu-inner > ul > li a:focus + div.sub,
#my-menu-inner > ul > li > div.sub:hover, #my-menu-inner > ul > li > div.sub:focus {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Simulate for Client supporting hover: <input type="checkbox" id="checkhover" />
<div id="my-menu">
<div id="my-menu-inner">
<ul class="clearfix">
<li>
<a href="http://www.example.com/foo/">foo</a>
<div class="sub">
<ul>
<li><a href="http://www.example.com/mobile/">mobile</a></li>
<li><a href="http://www.example.com/users/">users</a></li>
</ul>
</div>
</li>
<li>
<a href="http://www.example.com/bar/">bar</a>
<div class="sub">
<ul>
<li><a href="http://www.example.com/never/">never</a></li>
<li><a href="http://www.example.com/see-me/">see me</a></li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div id="for-no-hover-visitors"></div>
The problem is clientHasInputDeviceSupportingHover()
. What is the most reliable way to find this out?
What we know so far
It is possible to detect a touch device: What's the best way to detect a 'touch screen' device using JavaScript?
Mouse detection at least might work"onclick": How to detect if a device has mouse support?
In general there are a lot of different possible input devices: https://en.wikipedia.org/wiki/Input_device#Pointing_device
A generic / more reliable solution would be very welcome.