Join our webinar on Wednesday, June 26, at 1pm EDTHow Chia Mitigates Risk in the Crypto Industry.Register
Socket
Socket
Sign inDemoInstall

detect-it

Package Overview
Dependencies
5
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    detect-it

Detect if a device is mouse only, touch only, or hybrid


Version published
Weekly downloads
187K
decreased by-0.53%
Maintainers
1
Install size
63.6 kB
Created
Weekly downloads
 

Readme

Source

Detect It

Detect if a device is mouse only, touch only, or hybrid.

Live detection test

Exports a reference to a singleton object (a micro state machine with an update function) with its state set to if the device is mouse only, touch only, or hybrid (and other related info about the device), as well as an update() function which updates the object's state.

detect-it's state is a deterministic function of the state of the five micro state machines that it contains (detect-hover, detect-pointer, detect-touch-events, detect-pointer-events, and detect-passive-events). detect-it's update() function first runs the update() function on each micro state machine that it contains, and then updates it own state.

detectIt micro state machine

const detectIt = {
  deviceType: 'mouseOnly' / 'touchOnly' / 'hybrid',
  passiveEvents: boolean,
  hasTouchEventsApi: boolean,
  hasPointerEventsApi: boolean,
  hasTouch: boolean,
  maxTouchPoints: whole number,
  primaryHover: 'hover' / 'none',
  primaryPointer: 'fine' / 'coarse' / 'none',

  // access to the four micro state machines that it contains
  state: {
    detectHover,
    detectPointer,
    detectTouchEvents,
    detectPointerEvents,
    detectPassiveEvents,
  },

  // updates the state of the four micro state machines it contains, and then updates its own state
  update() {...},

  // easy access to detectPointerEvents' prefix function
  pointerEventsPrefix(value) {...},
}

Installing detect-it

$ npm install detect-it

Using detect-it

import detectIt from 'detect-it';
// using the state
detectIt.deviceType === 'mouseOnly' / 'touchOnly' / 'hybrid'; // the device type

detectIt.passiveEvents === true // the browser supports passive event listeners

detectIt.hasTouchEventsApi === true; // the browser supports the touch events api
detectIt.hasPointerEventsApi === true; // the browser supports the pointer events api

detectIt.hasTouch === true; // this is a touch capable device (no inference about api)
detectIt.maxTouchPoints; // max number of touch points supported

detectIt.primaryHover === 'hover' / 'none'; // can the primary pointing system easily hover
detectIt.primaryPointer === 'fine' / `coarse` / 'none'; // how accurate is the primary pointing system


// accessing the state of the micro state machines that detectIt contains
detectIt.state.detectHover; // see the detect-hover repo for more info
detectIt.state.detectPointer; // see the detect-pointer repo for more info
detectIt.state.detectTouchEvents; // see the detect-touch-events repo for more info
detectIt.state.detectPointerEvents; // see the detect-pointer-events repo for more info


// updating the state - most apps won't need to use this at all
detectIt.update();

// prefixing pointer events
detectIt.pointerEventsPrefix(value) // returns the value and only adds the prefix if it is required

// for example, this will add an event listener for 'MSPointerDown' if a prefix is required,
// otherwise it will add an event listener for 'pointerdown'
element.addEventListener(detectIt.pointerEventsPrefix('pointerdown'), function...)
/*
 * note that in the case of a legacy computer and browser, one that
 * doesn't support any of detect-it's detection tests, the default state will be:
 */
const detectIt = {
  deviceType: 'mouseOnly',
  passiveEvents: false,
  hasTouchEventsApi: false,
  hasPointerEventsApi: false,
  hasTouch: false,
  maxTouchPoints: undefined,
  primaryHover: 'hover',
  primaryPointer: 'fine',
}

/*
 * note that in the case of a legacy touch device, one that supports the touch events api,
 * but not any of the other detection tests, the default state will be:
 */
const detectIt = {
  deviceType: 'touchOnly',
  passiveEvents: false,
  hasTouchEventsApi: true,
  hasPointerEventsApi: false,
  hasTouch: true,
  maxTouchPoints: undefined,
  primaryHover: 'none',
  primaryPointer: 'coarse',
}

Note that the update() function is run once at the time of import to set the object's initial state, and generally doesn't need to be run again. If it doesn't have access to the window, then the state will be undefined (detect-it will not throw an error), and you will have to call the update() function manually at a later time to update its state.

Using detect-it to set event listeners (or just use the-listener)
const dIt = detectIt;

// if passive events are supported by the browser
if (dIt.passiveEvents === true) {
  document.addEventListener('scroll', handleScroll, { capture: false, passive: true });
} else {
  document.addEventListener('scroll', handleScroll, false);
}

// using mouse and touch events
if (dIt.deviceType === 'mouseOnly') {
  // only set mouse event listeners
}
if (dIt.deviceType === 'touchOnly' && dIt.hasTouchEventsApi) {
  // only set touch event listeners
}
if (dIt.deviceType === 'hybrid' && dIt.hasTouchEventsApi) {
  // set both mouse and touch event listeners
}

// note that there are cases where a touch capable device only fires pointer events
if (dIt.hasTouch && dIt.hasPointerEventsApi && !dIt.hasTouchEventsApi) {
  // must set pointer event listeners to access touch capabilities of device
  // note that dIt.hasTouch includes all touchOnly and hybrid devices
  // (you could be more specific and just target touchOnly or hybrid devices instead)
}

// using pointer events
if (dIt.hasPointerEventsApi) {
  // can set only pointer event listeners instead mouse and touch event listeners
}
if (dIt.deviceType === 'mouseOnly' && dIt.hasPointerEventsApi) {
  // can set only pointer event listeners knowing that the pointerType will only be mouse
  // (or can just set mouse event listeners instead of pointer event listeners)
}
if (dIt.deviceType === 'touchOnly' && dIt.hasPointerEventsApi) {
  // only set pointer event listeners knowing that pointerType will be pen or touch
  // (if the browser also hasTouchEventsApi, set either pointer or touch event listeners)
}
if (dIt.deviceType === 'hybrid' && dIt.hasPointerEventsApi) {
  // only set pointer event listeners knowing that pointerType could be mouse, pen, or touch
}
Using detect-it to adjust the user interface
const dIt = detectIt;

if (dIt.primaryPointer === 'coarse') {
  // make clickable elements bigger
}

if (dIt.primaryHover === 'hover') {
  // can add hover features
}
Real world examples using detect-it
  • react-interactive - a better interactive state machine than css
  • the-listener - easily set complex mouse, touch and pointer listeners without conflicts
  • current-input - detect the current input (mouse or touch) and fix the sticky hover problem on touch devices

Part of the detect-it family

For more information

Notes about detecting the deviceType

I chose a wide definition for what constitutes a hybrid device, or rather a strict definition for what are mouseOnly and touchOnly devices, because if a device strays from a fine point and hover with a mouse, or a coarse touch with a finger, then it should be treated uniquely when considering how the user will interact with it, and so is placed in the broad hybrid category.

// this is the function used by detect-it to determine the device type
function determineDeviceType(hasTouch, anyHover, anyFine) {
  /*
   * A hybrid device is one that both hasTouch and any input device can hover
   * or has a fine pointer. Note that hasTouch only reflects the capabilities
   * of the device, but provides no inference about the api.
   */
  if (hasTouch && (anyHover || anyFine)) return 'hybrid';

  /*
   * In almost all cases a device that doesn’t support touch will have a mouse,
   * but there may be rare exceptions. Note that it doesn’t work to do additional tests
   * based on hover and pointer media queries as older browsers don’t support these.
   * Essentially, 'mouseOnly' is the default.
   */
  return hasTouch ? 'touchOnly' : 'mouseOnly';
}

Some hybrid examples:

  • A touch capable Chromebook with Chrome browser registers that hasTouch, anyHover, and anyFine are all true (and that hasTouchEventsApi is true).
  • The Galaxy Note with stylus running the Chrome mobile browser registers that hasTouch and anyFine are true, but that anyHover is false (and that hasTouchEventsApi is true) - as a side note I think that since the stylus hovers effectively, the Note should register as anyHover true, but for some reason it doesn't.
  • The Microsoft Surface (and other Windows 10 touchscreen computers) register that hasTouch, anyHover and anyFine are all true for both Microsoft Edge and Chrome browsers (note that for the Edge browser hasPointerEventsApi is true, but hasTouchEventsApi is false, and for the Chrome browser hasTouchEventsApi is true, but hasPointerEventsApi is false).

Keywords

FAQs

Last updated on 08 Nov 2016

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc