JavaScript mapping touch events to mouse events
I am sure this is what you want:
function touchHandler(event)
{
var touches = event.changedTouches,
first = touches[0],
type = "";
switch(event.type)
{
case "touchstart": type = "mousedown"; break;
case "touchmove": type = "mousemove"; break;
case "touchend": type = "mouseup"; break;
default: return;
}
// initMouseEvent(type, canBubble, cancelable, view, clickCount,
// screenX, screenY, clientX, clientY, ctrlKey,
// altKey, shiftKey, metaKey, button, relatedTarget);
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);
first.target.dispatchEvent(simulatedEvent);
event.preventDefault();
}
function init()
{
document.addEventListener("touchstart", touchHandler, true);
document.addEventListener("touchmove", touchHandler, true);
document.addEventListener("touchend", touchHandler, true);
document.addEventListener("touchcancel", touchHandler, true);
}
I've captured the touch events and then manually fired my own mouse events to match. Although the code isn't particularly general purpose as is, it should be trivial to adapt to most existing drag and drop libraries, and probably most existing mouse event code. Hopefully this idea will come in handy to people developing web applications for the iPhone.Update:
In posting this, I noticed that calling preventDefault
on all touch events will prevent links from working properly. The main reason to call preventDefault
at all is to stop the phone from scrolling, and you can do that by calling it only on the touchmove
callback. The only downside to doing it this way is that the iPhone will sometimes display its hover popup over the drag origin. If I discover a way to prevent that, I'll update this post.
Second Update:
I've found the CSS property to turn off the callout: -webkit-touch-callout
.
Need to convert Mouse events to Touch Events for mobile using HTML Canvas
Actually it is as easy as listening for both - touch and mouse - events.
The touchstart
event is the mousedown
, the touchmove
the mousemove
and lastly touchend
is the mouseup
equivalent.
Theoretically you could simply add the same callback functions to all of these listeners. The only problem is you can't directly query the 'mouse' position using the event.clientX
property inside the callback function. That's because there can be multiple touches while there is always just a single mouse event. To keep track of the touches, those are stored in a TouchList
- more or less an array - which is the .touches
property of the event.
So we need to make a distinction between a mouse and a touch event inside the callback function:
- If it's a touch use
event.touches[0].clientX
- If it's a mouse event use
event.clientX
var canvas = document.createElement('canvas');
canvas.id = "canvas";
document.body.appendChild(canvas);
document.body.style.margin = 0;
canvas.style.position = 'relative';
var ctx = canvas.getContext('2d');
resize();
var pos = {
x: 0,
y: 0
};
var buttonDown = false;
const cvs = document.getElementById("canvas");
cvs.addEventListener('mousedown', getRandomInt);
cvs.addEventListener('touchstart', getRandomInt);
window.addEventListener('resize', resize);
document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
document.addEventListener('mouseup', released);
document.addEventListener('touchstart', setPosition);
document.addEventListener('touchmove', draw);
document.addEventListener('touchend', released);
function getRandomInt() {
window.randInt = Math.floor(Math.random() * Math.floor(3));
}
function released(e) {
buttonDown = false;
}
function setPosition(e) {
if (e.type == "touchstart" || e.type == "mousedown") {
buttonDown = true;
}
if (e.type == "touchstart" || e.type == "touchmove") {
pos.x = e.touches[0].clientX;
pos.y = e.touches[0].clientY;
} else {
pos.x = e.clientX;
pos.y = e.clientY;
}
}
function resize() {
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
function draw(e) {
if (!buttonDown) return;
var color = '';
switch (window.randInt) {
case 1:
color = 'green';
break;
case 2:
color = 'red';
break;
case 0:
color = 'blue';
break;
}
ctx.beginPath();
ctx.lineWidth = 3;
ctx.lineCap = 'round';
ctx.strokeStyle = color;
ctx.moveTo(pos.x, pos.y);
setPosition(e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
}
handle both mouse and touch events on touch screens
You should rather check availability of touch interface and bind events according to that.
You can do something like this:
(function () {
if ('ontouchstart' in window) {
window.Evt = {
PUSH : 'touchstart',
MOVE : 'touchmove',
RELEASE : 'touchend'
};
} else {
window.Evt = {
PUSH : 'mousedown',
MOVE : 'mousemove',
RELEASE : 'mouseup'
};
}
}());
// and then...
document.getElementById('mydiv').addEventListener(Evt.PUSH, myStartDragHandler, false);
If you want to handle both in same time and browser does not translate well touch events into mouse events, you can catch touch events and stop them - then corresponding mouse event shouldn't be fired by browser (you won't have double events) and you can fire it yourself as mouse event or just handle it.
var mydiv = document.getElementsById('mydiv');
mydiv.addEventListener('mousemove', myMoveHandler, false);
mydiv.addEventListener('touchmove', function (e) {
// stop touch event
e.stopPropagation();
e.preventDefault();
// translate to mouse event
var clkEvt = document.createEvent('MouseEvent');
clkEvt.initMouseEvent('mousemove', true, true, window, e.detail,
e.touches[0].screenX, e.touches[0].screenY,
e.touches[0].clientX, e.touches[0].clientY,
false, false, false, false,
0, null);
mydiv.dispatchEvent(clkEvt);
// or just handle touch event
myMoveHandler(e);
}, false);
mouse events to touch event for ipad compatibility
You can map it like this:
$('#drawingCanvas').bind("mousedown touchstart", function(e){
$('#drawingCanvas').bind("mousemove touchmove", function(e){
$('#drawingCanvas').bind("mouseup touchend", function(e){
And than finetune the code if needed. Touch event for mouseover
Virtual mouse event by JQuery mobile
is quite welldone.
https://api.jquerymobile.com/vmouseover/
Related Topics
React Jsx: Selecting "Selected" on Selected <Select> Option
If (Key in Object) or If(Object.Hasownproperty(Key)
Keep Bootstrap Dropdown Open When Clicked Off
What Do Double Brackets Mean in JavaScript and How to Access Them
How to Detect When a Tab Is Focused or Not in Chrome with JavaScript
Detect 64-Bit or 32-Bit Windows from User Agent or JavaScript
How to Find Out with Jquery If an Element Is Being Animated
Updating Svg Element Z-Index with D3
How to Check Dimensions of Image Before Uploading
How Does Setinterval and Settimeout Work
Google Map API - Multiple Icons in Wrong Spot
Jquery Smooth Scroll to an Anchor
JavaScript Loop Variable Scope
JavaScript Getelementbyname Doesn't Work
Why Are Exceptions Used for Rejecting Promises in Js
Javascript: Unicode String to Hex