Skip to content

Instantly share code, notes, and snippets.

@bmcminn
Last active May 22, 2018 18:09
Show Gist options
  • Save bmcminn/634728145a3c120103d9a497f37e55f8 to your computer and use it in GitHub Desktop.
Save bmcminn/634728145a3c120103d9a497f37e55f8 to your computer and use it in GitHub Desktop.
Simple demo of pointer detection for preventing hover states from click-jacking mobile device input. (NOTE: this was inspired by a similar script I can't find the source for, but will update when I do)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Touch Vs. No-touch hover helpers</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/5.0.0/sanitize.min.css">
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css"> -->
<style type="text/css">
:root{
--color-hover: #06f;
}
body {
font-family: sans-serif;
text-align: center;
min-height: 100vh;
font-size: 100%;
}
button {
position: absolute;
top: 50%;
padding: 1em;
border-radius: 0.3em;
border: 1px solid #ccc;
transform: translate(-50%, -50%);
transition: all 0.3s linear;
}
.no-touch button:hover {
cursor: pointer;
background-color: var(--color-hover);
color: white;
border-color: var(--color-hover);
}
</style>
</head>
<body>
<button>Click me!</button>
<script type="text/javascript">
let btn = document.querySelector('button');
// set event handler for button
btn.addEventListener('click', function(e) {
console.log('The button was', e.type + 'ed');
}, false);
/**
* Debounce: throttle all the things more for performance and profit
* @sauce: https://davidwalsh.name/javascript-debounce-function
* @sauce: http://underscorejs.org/#debounce
* @param {function} func The function to be debounced
* @param {integer} wait The time in milliseconds to delay execution before checking the event
* @param {boolean} immediate Boolean flag to trigger the callback before timeout is checked instead of after
* @return {function} Returns a new version of the original function to be called on the next timeout cycle
*/
function debounce(func, wait, immediate) {
let timeout;
return function() {
let context = this, args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
/**
* Toggles no-hover and no-touch states based on pointer input type
* @param {event} The event object
*/
let touchVsMouse = debounce(function (e) {
// console.log(e);
// on touch, disable hover
if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) {
document.documentElement.classList.add('no-hover');
document.documentElement.classList.remove('no-touch');
btn.innerText = 'Touch me!';
return;
// else enable hover
} else {
document.documentElement.classList.add('no-touch');
document.documentElement.classList.remove('no-hover');
btn.innerText = 'Click me!';
return;
}
}, 200, true);
// Register click/touch event handler(s)
document.addEventListener('mousemove', touchVsMouse, false);
document.addEventListener('touchstart', touchVsMouse, false);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment