Skip to content

Instantly share code, notes, and snippets.

@lmeurs
Last active April 4, 2023 18:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lmeurs/e5db12f0b3ef43f9cd65 to your computer and use it in GitHub Desktop.
Save lmeurs/e5db12f0b3ef43f9cd65 to your computer and use it in GitHub Desktop.
Touch Or Mouse: A jQuery plugin that detects whether an event has been invoked by a touchscreen or a mouse.
/*! Touch Or Mouse - v0.2 - 2014-10-10
* Shared at https://gist.github.com/lmeurs/e5db12f0b3ef43f9cd65
* Demonstrated at http://jsfiddle.net/lmeurs/uo4069nh
* Discussed at http://stackoverflow.com/a/26145343/328272
* Copyright (c) 2014 Laurens Meurs, wiedes.nl; Licensed MIT */
/**
* Touch Or Mouse: A jQuery plugin that detects whether an event has been
* invoked by a touchscreen or a mouse.
*
* @param action
* Possible values are "init" and "get".
*
* @param optionsOrEvent
* On init: Options object.
* On get: Event object.
*
* @return
* On init: jQuery collection.
* On get: "touch" or "mouse" string.
*/
(function($) {
"use strict";
// Define default options.
var defaultOptions = {
// If a mouse event is being fired shortly after a touch end event, it is
// considered to be a ghost event and thus marked as touch.
ghostEventDelay: 1000
};
// Actions object.
var actions = {
// Initialize touch event tracking element.
init: function(options) {
// Get touch event tracking element (ie. the body element).
var $touchEventTrackingElement = this;
// The touch event tracking element has not been initialized when it does
// not have a touchOrMouse data object.
if (!$touchEventTrackingElement.data('touchOrMouse')) {
// Initialize touch event tracking element...
$touchEventTrackingElement
// ...by binding touch start and end events...
.on('touchstart.touchOrMouse touchend.touchOrMouse', function(e) {
// Set flag that indicates whether a touch event is in progress.
$(this).data('touchOrMouse').touchEventInProgress = e.type === 'touchstart';
// Update last touch event timestamp to detect ghost events.
$(this).data('touchOrMouse').lastTouchEventTimestamp = Date.now();
})
// ...and creating touchOrMouse data object.
.data('touchOrMouse', {
// Merge default with user options.
options: $.extend(defaultOptions, options || {}),
// Flag that indicates wheter a touch event is in progress.
touchEventInProgress: false,
// Timestamp of last touch event.
lastTouchEventTimestamp: 0
});
}
// Return collection.
return $touchEventTrackingElement;
},
// Get whether an event is invoked by touch or mouse.
get: function(e) {
// Get touch event tracking element (ie. the body element).
var $touchEventTrackingElement = this,
// Get touch event tracking element 's touchOrMouse data object.
touchEventTrackingElementData = $touchEventTrackingElement.data('touchOrMouse'),
// Get mouse event firing element's (ie. a button) touchOrMouse data object.
mouseEventFiringElementData = $(e.delegateTarget).data('touchOrMouse');
// Create touchOrMouse data object for mouse event firing element.
if (!mouseEventFiringElementData) {
$(e.delegateTarget).data('touchOrMouse', mouseEventFiringElementData = {});
}
// Set isTouch flag to true if touch event is in progress,
var isTouch = touchEventTrackingElementData.touchEventInProgress
// if event is considered to be a ghost event or
|| touchEventTrackingElementData.lastTouchEventTimestamp > Date.now() - touchEventTrackingElementData.options.ghostEventDelay
// if event is mouseleave and the last mouseenter event was invoked by touch
|| e.type === 'mouseleave' && mouseEventFiringElementData.lastMouseEnterEventWasInvokedByTouch;
// In case of mouseenter event.
if (e.type === 'mouseenter') {
// Store for the mouse event firing element whether the current event
// was invoked by touch.
mouseEventFiringElementData.lastMouseEnterEventWasInvokedByTouch = isTouch;
}
// Return "touch" or "mouse".
return isTouch ? 'touch' : 'mouse'
}
};
// Register plugin.
$.fn.touchOrMouse = function(action, optionsOrEvent) {
// Call action.
return actions[action].call(this, optionsOrEvent);
};
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment