Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0fc53bc
Updated to v1.0.0 to combine suggested changes
RWAP Jan 29, 2019
7cdb489
Update to cover why new fork created
RWAP Jan 29, 2019
44205e8
Removed change for zoomed devices
RWAP Jan 29, 2019
e922197
Notes on jquery-ui dialog and close button
RWAP Jan 31, 2019
8c747e7
Update for Apple Pencil
RWAP Jun 3, 2019
ccb585e
Merge pull request #3 from RWAP/RWAP-patch-1
RWAP Jun 11, 2019
ab14010
FIx #4 - mouse undefined
RWAP Jun 11, 2019
80d8496
Typo in last commit
RWAP Jun 11, 2019
1693eb3
v1.0.3 Release - Change to handling of click events
RWAP Jun 24, 2019
3c93442
Correct patch as per original v1.0.2 code
RWAP Jun 24, 2019
5d62cb0
Merge pull request #5 from RWAP/RWAP-patch-1
RWAP Jun 24, 2019
d4d7900
Prevent simulation of two clicks when interaction hasn't moved
provegard Aug 3, 2019
b6a980a
Merge pull request #6 from provegard/master
RWAP Aug 3, 2019
64128a0
Updated for jQuery v3
RWAP Aug 19, 2019
6def982
v1.0.5 - Update to support Lenova touch screen
RWAP Aug 20, 2019
de83557
Update Header Comments
RWAP Aug 21, 2019
81fcc4e
Remove minified version
RWAP Aug 22, 2019
a25ec59
Readme updated - removal of minified version
RWAP Aug 22, 2019
4c3af76
Update re Issue #13
RWAP Jan 15, 2020
defa149
Updated version number
RWAP Jan 15, 2020
44744c2
fix errors while using draggable during mobile scrolling
SebouChu Feb 24, 2020
c1817d4
Change version
SebouChu Feb 24, 2020
62a8c45
Merge pull request #15 from SebouChu/master
RWAP Feb 24, 2020
3f43506
v1.0.8 - MS Surface Devices
RWAP Oct 22, 2020
4fa24de
Added package.json
Jul 25, 2022
c973edc
Merge pull request #24 from naitsirch/package_json
RWAP Jul 25, 2022
40769de
Defining jquery-ui as dependency instead of jquery.ui
Jul 25, 2022
bb49a73
Merge pull request #25 from naitsirch/jqueryui_di_fix
RWAP Jul 25, 2022
cc99049
Delete bower.json
RWAP Jul 27, 2022
965c895
Update package.json
RWAP Jul 27, 2022
c06e775
Update package.json
RWAP Jul 27, 2022
f4a11ba
Ignore where pointer is over an input or textarea
RWAP Feb 25, 2023
c28c0a6
Merge pull request #32 from RWAP/RWAP-patch-2
RWAP Feb 25, 2023
cac84b6
Incorporate minor changes from Nitrotap
RWAP Feb 26, 2023
970cab8
Update Readme info
RWAP Feb 26, 2023
eb5432f
Update: initMouseEvent() is deprecated
RWAP Mar 6, 2024
f847786
Change deprecated $.proxy use
RWAP Mar 6, 2024
9efd7e1
Replace deprecated $.fn.bind/unbind
smartexcan Mar 8, 2024
ed60e6d
Merge pull request #36 from smartexcan/master
RWAP Mar 8, 2024
761d634
Update jquery.ui.touch-punch.js version
RWAP Mar 8, 2024
9c30b5b
v1.1.3
RWAP Mar 8, 2024
7d0aed3
Update package.json
RWAP Mar 8, 2024
9993228
Double Click support and incorrect use of MouseEvent function (#37)
calanor Mar 12, 2024
137a747
Updated to v1.1.4
RWAP Mar 12, 2024
54639b5
v1.1.5 Update
RWAP Apr 23, 2024
4097b0d
Update package.json
RWAP Apr 24, 2024
1392495
Update README.md
RWAP Apr 24, 2024
3e5928f
Update README.md
RWAP Apr 24, 2024
8d3a0a2
Fix touch handler binding across multiple widgets and improve msPoint…
alexanderternst Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@

> **jQuery UI Touch Punch is a small hack that enables the use of touch events on sites using the jQuery UI user interface library.**

_[Visit the official Touch Punch website](http://touchpunch.furf.com)._

Currently, [jQuery UI](http://jqueryui.com/) user interface library does not support the use of touch events in their widgets and interactions. This means that the slick UI you designed and tested in your desktop browser will fail on most, if not all, touch-enabled mobile devices, because jQuery UI listens to mouse events—mouseover, mousemove and mouseout—not touch events—touchstart, touchmove and touchend.

That's where jQuery UI Touch Punch comes in. Touch Punch works by using [simulated events](https://developer.mozilla.org/en/DOM/document.createEvent) to map [touch events](http://www.html5rocks.com/en/mobile/touch/) to their mouse event analogs. Simply include the script on your page and your touch events will be turned into their corresponding mouse events to which jQuery UI will respond as expected.

As I said, Touch Punch is a hack. It [duck punches](http://en.wikipedia.org/wiki/Monkey_patch) some of jQuery UI's core functionality to handle the mapping of touch events. Touch Punch works with all basic implementations of jQuery UI's interactions and widgets. However, you may find more complex cases where Touch Punch fails. If so, scroll down to learn how you can file and/or fix issues.

This code is dual licensed under the MIT or GPL Version 2 licenses and is therefore free to use, modify and/or distribute, but if you include Touch Punch in other software packages or plugins, please include an attribution to the original software and a link to [this Touch Punch website](http://touchpunch.furf.com/).
This code is dual licensed under the MIT or GPL Version 2 licenses and is therefore free to use, modify and/or distribute, but if you include Touch Punch in other software packages or plugins, please include an attribution to the original software and a link to [this repo](https://github.com/RWAP/jquery-ui-touch-punch).

Fork: https://github.com/RWAP/jquery-ui-touch-punch

RWAP Version (2019-2024)

The [original repo](https://github.com/furf/jquery-ui-touch-punch) was last updated in 2014.

I have created a new fork which contains various suggested improvements to the code when it became clear that touch-punch does not work too well on Android devices, and actually stopped the close button on jquery-ui dialogs from working on some devices.

www.rwapsoftware.co.uk


## Using Touch Punch is as easy as 1, 2…

Expand All @@ -29,7 +38,7 @@ Just follow these simple steps to enable touch events in your jQuery UI app:
Please note that if you are using jQuery UI's components, Touch Punch must be included after jquery.ui.mouse.js, as Touch Punch modifies its behavior.

```html
<script src="jquery.ui.touch-punch.min.js"></script>
<script src="jquery.ui.touch-punch.js"></script>
```

3. There is no 3. Just use jQuery UI as expected and watch it work at the touch of a finger.
Expand All @@ -39,3 +48,15 @@ Just follow these simple steps to enable touch events in your jQuery UI app:
```

_Tested on iPad, iPhone, Android and other touch-enabled mobile devices._

## If it does not seem to work…

Remember that Touch Punch is just allowing various key strokes (such as touch, cliuck and double click) to emulate mouse movements. We do nothing with the underlying jQuery code.

If it does not appear to work for you:

1. Ensure that you are using the latest version of this plugin (and not the [original repo](https://github.com/furf/jquery-ui-touch-punch) ).

2. Ensure that you have the latest versions of jQuery and jQuery UI linked in your webpage, BEFORE this code

3. Ensure that the original code works as expected on desktop.
10 changes: 0 additions & 10 deletions bower.json

This file was deleted.

9 changes: 9 additions & 0 deletions jquery-ui-notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Whilst implementing this, we noticed that on some mobile phones there were still some issues:

a) If you have a jquery-ui dialog box open, it could be nigh impossible to use the close icon in the top right hand
corner on some phones.
After some experimentation, we found that we had to check if the screen size <= 480 and in that case, set the dialog
"draggable" setting to false

Presumably the phone was struggling to work out if we were trying to drag a box which might only be a couple of pixels smaller
than the width of the screen, or we wanted to hit the close icon.
177 changes: 124 additions & 53 deletions jquery.ui.touch-punch.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,62 @@
/*!
* jQuery UI Touch Punch 0.2.3
* jQuery UI Touch Punch 1.1.5 as modified by RWAP Software
* based on original touchpunch v0.2.3 which has not been updated since 2014
*
* Updates by RWAP Software to take account of various suggested changes on the original code issues
*
* Original: https://github.com/furf/jquery-ui-touch-punch
* Copyright 2011–2014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Fork: https://github.com/RWAP/jquery-ui-touch-punch
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function ($) {

// Detect touch support
$.support.touch = 'ontouchend' in document;
(function( factory ) {
if ( typeof define === "function" && define.amd ) {

// AMD. Register as an anonymous module.
define([ "jquery", "jquery-ui" ], factory );
} else {

// Ignore browsers without touch support
if (!$.support.touch) {
return;
// Browser globals
factory( jQuery );
}
}(function ($) {

// Detect touch support - Windows Surface devices and other touch devices
$.mspointer = window.navigator.msPointerEnabled;
$.touch = ( 'ontouchstart' in document
|| 'ontouchstart' in window
|| window.TouchEvent
|| (window.DocumentTouch && document instanceof DocumentTouch)
|| navigator.maxTouchPoints > 0
|| navigator.msMaxTouchPoints > 0
);

// Ignore browsers without touch or mouse support
if ((!$.touch && !$.mspointer) || !$.ui.mouse) {
return;
}

var mouseProto = $.ui.mouse.prototype,
let mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
_mouseDestroy = mouseProto._mouseDestroy,
touchHandled;
touchHandled, lastClickTime = 0;

/**
* Get the x,y position of a touch event
* @param {Object} event A touch event
*/
function getTouchCoords (event) {
return {
x: event.originalEvent.changedTouches[0].pageX,
y: event.originalEvent.changedTouches[0].pageY
};
}

/**
* Simulate a mouse event based on a corresponding touch event
Expand All @@ -35,29 +70,26 @@
return;
}

event.preventDefault();

var touch = event.originalEvent.changedTouches[0],
simulatedEvent = document.createEvent('MouseEvents');

// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);
//Ignore input or textarea elements so user can still enter text
if ($(event.target).is("input") || $(event.target).is("textarea")) {
return;
}

// Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors
if (event.cancelable) {
event.preventDefault();
}

let touch = event.originalEvent.changedTouches[0],
simulatedEvent = new MouseEvent(simulatedType, {
bubbles: true,
cancelable: true,
view:window,
screenX:touch.screenX,
screenY:touch.screenY,
clientX:touch.clientX,
clientY:touch.clientY
});

// Dispatch the simulated event to the target element
event.target.dispatchEvent(simulatedEvent);
Expand All @@ -69,7 +101,13 @@
*/
mouseProto._touchStart = function (event) {

var self = this;
let self = this;

// Interaction time
this._startedMove = event.timeStamp;

// Track movement to determine if interaction was a click
self._startPos = getTouchCoords(event);

// Ignore the event if another widget is already being handled
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
Expand Down Expand Up @@ -103,7 +141,7 @@
return;
}

// Interaction was not a click
// Interaction was moved
this._touchMoved = true;

// Simulate the mousemove event
Expand All @@ -128,12 +166,31 @@
simulateMouseEvent(event, 'mouseout');

// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved) {

// Simulate the click event
simulateMouseEvent(event, 'click');
// Check for this in two ways - length of time of simulation and distance moved
// Allow for Apple Stylus to be used also
let timeMoving = event.timeStamp - this._startedMove;
if (!this._touchMoved || timeMoving < 500) {
// Simulate the click event
if( event.timeStamp - lastClickTime < 400 )
simulateMouseEvent(event, 'dblclick');
else
simulateMouseEvent(event, 'click');
lastClickTime = event.timeStamp;
} else {
let endPos = getTouchCoords(event);
if ((Math.abs(endPos.x - this._startPos.x) < 10) && (Math.abs(endPos.y - this._startPos.y) < 10)) {

// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved || event.originalEvent.changedTouches[0].touchType === 'stylus') {
// Simulate the click event
simulateMouseEvent(event, 'click');
}
}
}

// Unset the flag to determine the touch movement stopped
this._touchMoved = false;

// Unset the flag to allow other widgets to inherit the touch event
touchHandled = false;
};
Expand All @@ -145,14 +202,23 @@
* original mouse event handling methods.
*/
mouseProto._mouseInit = function () {

var self = this;

let self = this;

// Microsoft Surface Support = remove original touch Action
if ($.mspointer || ($.support && $.support.mspointer)) {
self.element[0].style.msTouchAction = 'none';
}

self._touchStartBound = mouseProto._touchStart.bind(self);
self._touchMoveBound = mouseProto._touchMove.bind(self);
self._touchEndBound = mouseProto._touchEnd.bind(self);

// Delegate the touch handlers to the widget's element
self.element.bind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
self.element.on({
touchstart: self._touchStartBound,
touchmove: self._touchMoveBound,
touchend: self._touchEndBound
});

// Call the original $.ui.mouse init method
Expand All @@ -163,18 +229,23 @@
* Remove the touch event handlers
*/
mouseProto._mouseDestroy = function () {
var self = this;

let self = this;

// Delegate the touch handlers to the widget's element
self.element.unbind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
self.element.off({
touchstart: self._touchStartBound,
touchmove: self._touchMoveBound,
touchend: self._touchEndBound
});

// Clean up references
self._touchStartBound = null;
self._touchMoveBound = null;
self._touchEndBound = null;

// Call the original $.ui.mouse destroy method
_mouseDestroy.call(self);
};

})(jQuery);
}));
11 changes: 0 additions & 11 deletions jquery.ui.touch-punch.min.js

This file was deleted.

15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "@rwap/jquery-ui-touch-punch",
"version": "1.1.5",
"description": "A duck punch for adding touch events to jQuery UI",
"browser": "jquery.ui.touch-punch.js",
"repository": "https://github.com/RWAP/jquery-ui-touch-punch.git",
"author": "Rich M <[email protected]>",
"contributors": [
"Dave Furfero <[email protected]>"
],
"license": "MIT or GPL version 2",
"dependencies": {
"jquery-ui": ">=1.8"
}
}