Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 26 additions & 25 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
.idea/
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ npm install hammer-touchemulator
```

## How to use
Include the javascript file, and call the `Emulator()` function before any other libraries that do something with the
Include the javascript file, and call `TouchEmulator.start()` before any other libraries that do something with the
touch input. It will set some fake properties to spoof the touch detection of some libraries, and triggers `touchstart`, `touchmove` and `touchend` events on the mouse target.

````html
<script src="touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>
````

````js
Expand All @@ -42,6 +42,9 @@ document.body.addEventListener('touchend', log, false);

Also, the script includes polyfills for `document.createTouch` and `document.createTouchList`.

You can stop the touch emulator with `TouchEmulator.stop()` and restart it with another call to `TouchEmulator.start()`.
In previous versions, the emulator was started by calling `TouchEmulator()`; that continues to work, too.

## How it works
It listens to the `mousedown`, `mousemove` and `mouseup` events, and translates them to touch events. If the mouseevent
has the `shiftKey` property to `true`, it enables multi-touch.
Expand Down
37 changes: 37 additions & 0 deletions tests/manual/events-restarted.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator.start(); </script>
</head>
<body>

<div id="hitarea" style="background: silver; height: 400px;">
Check the console. No mouse events should be fired, only touch events. Click events are allowed.
</div>

<script>

function log(ev) {
console.log(ev.type, ev);
}

var hitarea = document.getElementById('hitarea');

var events = ['touchstart','touchmove','touchend','touchcancel',
'mousedown','mouseenter','mouseleave','mousemove',
'mouseout','mouseover','mouseup','mousewheel',
'click'];

for(var i=0; i<events.length; i++) {
hitarea.addEventListener(events[i], log, false);
}

TouchEmulator.stop();
TouchEmulator.start();
</script>
</body>
</html>
36 changes: 36 additions & 0 deletions tests/manual/events-stopped.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator.start(); </script>
</head>
<body>

<div id="hitarea" style="background: silver; height: 400px;">
Check the console. No touch events should be fired, only mouse events. Click events are allowed, too.
</div>

<script>

function log(ev) {
console.log(ev.type, ev);
}

var hitarea = document.getElementById('hitarea');

var events = ['touchstart','touchmove','touchend','touchcancel',
'mousedown','mouseenter','mouseleave','mousemove',
'mouseout','mouseover','mouseup','mousewheel',
'click'];

for(var i=0; i<events.length; i++) {
hitarea.addEventListener(events[i], log, false);
}

TouchEmulator.stop();
</script>
</body>
</html>
4 changes: 2 additions & 2 deletions tests/manual/events.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<title></title>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>
</head>
<body>

<div id="hitarea" style="background: silver; height: 400px;">
Check the console. No mouseevents should be fired, only touchevents. Click events are allowed.
Check the console. No mouse events should be fired, only touch events. Click events are allowed.
</div>

<script>
Expand Down
2 changes: 1 addition & 1 deletion tests/manual/googlemaps.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
Expand Down
2 changes: 1 addition & 1 deletion tests/manual/hammer.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</style>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>
</head>
<body>

Expand Down
2 changes: 1 addition & 1 deletion tests/manual/img.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<title></title>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>
</head>
<body>
no dragging of images;<br>
Expand Down
2 changes: 1 addition & 1 deletion tests/manual/leaflet.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<title></title>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion tests/manual/modernizr.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<h1>Can we trick Modernizr?</h1>

<script src="../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.min.js"></script>
<script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<meta name="viewport" content="width=device-width">

<script src="../../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<meta name="viewport" content="width=device-width">

<script src="../../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<meta name="viewport" content="width=device-width">

<script src="../../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="../resources/testharness.js"></script>
<script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<meta name="viewport" content="width=device-width">

<script src="../../../touch-emulator.js"></script>
<script> TouchEmulator(); </script>
<script> TouchEmulator.start(); </script>

<script src="../resources/testharness.js"></script>
<script>
Expand Down
74 changes: 61 additions & 13 deletions touch-emulator.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
(function(window, document, exportName, undefined) {
"use strict";

var isRunning = false;
var isMultiTouch = false;
var multiTouchStartPos;
var eventTarget;
var touchElements = {};
var fakedProps = [];
var handlers = [];

// polyfills
if(!document.createTouch) {
Expand Down Expand Up @@ -94,11 +97,23 @@
for(var p=0; p<props.length; p++) {
if(objs[o] && objs[o][props[p]] == undefined) {
objs[o][props[p]] = null;
fakedProps.push({prop: props[p], context: objs[o]});
}
}
}
}

/**
* revert to the state without fake touch support
*/
function removeFakeTouchSupport() {
for(var i=0; i<fakedProps.length; i++) {
delete fakedProps[i].context[fakedProps[i].prop];
}

fakedProps = [];
}

/**
* we don't have to emulate on a touch device
* @returns {boolean}
Expand Down Expand Up @@ -287,31 +302,64 @@
}
}

/**
* add an event handler and keep track of it
* @param {string} event
* @param {Function} handler
*/
function addHandler(event, handler) {
handlers.push({event: event, handler: handler});
window.addEventListener(event, handler, true);
}

/**
* remove all event handlers which have been added by the emulator
*/
function removeHandlers() {
for(var i=0; i<handlers.length; i++) {
window.removeEventListener(handlers[i].event, handlers[i].handler, true);
}

handlers = [];
}

/**
* TouchEmulator initializer
*/
function TouchEmulator() {
if (hasTouchSupport()) {
TouchEmulator.start();
}

TouchEmulator.start = function () {
if (isRunning || hasTouchSupport()) {
return;
}

fakeTouchSupport();

window.addEventListener("mousedown", onMouse('touchstart'), true);
window.addEventListener("mousemove", onMouse('touchmove'), true);
window.addEventListener("mouseup", onMouse('touchend'), true);
addHandler("mousedown", onMouse('touchstart'));
addHandler("mousemove", onMouse('touchmove'));
addHandler("mouseup", onMouse('touchend'));

window.addEventListener("mouseenter", preventMouseEvents, true);
window.addEventListener("mouseleave", preventMouseEvents, true);
window.addEventListener("mouseout", preventMouseEvents, true);
window.addEventListener("mouseover", preventMouseEvents, true);
addHandler("mouseenter", preventMouseEvents);
addHandler("mouseleave", preventMouseEvents);
addHandler("mouseout", preventMouseEvents);
addHandler("mouseover", preventMouseEvents);

// it uses itself!
window.addEventListener("touchstart", showTouches, true);
window.addEventListener("touchmove", showTouches, true);
window.addEventListener("touchend", showTouches, true);
window.addEventListener("touchcancel", showTouches, true);
}
addHandler("touchstart", showTouches);
addHandler("touchmove", showTouches);
addHandler("touchend", showTouches);
addHandler("touchcancel", showTouches);

isRunning = true;
};

TouchEmulator.stop = function () {
removeFakeTouchSupport();
removeHandlers();
isRunning = false;
};

// start distance when entering the multitouch mode
TouchEmulator.multiTouchOffset = 75;
Expand Down