From 30e770561d0e8c3179fc55f306d48d6bde034373 Mon Sep 17 00:00:00 2001 From: atomiks Date: Sat, 30 Dec 2017 02:41:53 +1100 Subject: [PATCH] Create onUserInputChange.md --- snippets/onUserInputChange.md | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 snippets/onUserInputChange.md diff --git a/snippets/onUserInputChange.md b/snippets/onUserInputChange.md new file mode 100644 index 000000000..f54d84e76 --- /dev/null +++ b/snippets/onUserInputChange.md @@ -0,0 +1,43 @@ +### onUserInputChange + +Will run the callback whenever the user changes their input type (either `mouse` or `touch`). This is useful +if you want to disable certain code depending on if the user is using touch as input or a mouse (including trackpads). + +Use two event listeners. Assume `mouse` input initially and bind a `touchstart` event listener to the document. +On `touchstart`, the callback is run and supplied with the current input type as an argument. +Then, add a `mousemove` event listener to listen for two consecutive `mousemove` events firing within 20ms +using `performance.now()` (browsers recently fire them every animation frame). Run the callback and supply the new type +`mouse` as the argument. This process needs to happen dynamically because of hybrid devices (such as a touchscreen laptop), +where the user can switch between either input type at will. + +```js +const onUserInputChange = callback => { + let type = 'mouse'; + + const mousemoveHandler = (() => { + let lastTime = 0; + return () => { + const now = performance.now(); + if (now - lastTime < 20) { + type = 'mouse'; + callback(type); + document.removeEventListener('mousemove', mousemoveHandler); + } + lastTime = now; + } + })(); + + document.addEventListener('touchstart', () => { + if (type === 'touch') return; + type = 'touch'; + callback(type); + document.addEventListener('mousemove', mousemoveHandler) + }); +}; +``` + +```js +onUserInputChange(type => { + console.log('The user is now using', type, 'as an input method.'); +}); +```