eventi Generazione del mouse da eventi touch
OK visto questa domanda qui per un po 'e nessuno è venuta avanti con una risposta darò uno.
Gli eventi di tocco diversi dagli eventi del mouse riguardano molti punti di contatto con l'interfaccia utente. Per adattarsi a questo, gli eventi touch forniscono una serie di punti di contatto. Poiché un mouse non può essere in due posti contemporaneamente, i due metodi di interazione dovrebbero essere gestiti separatamente per la migliore esperienza utente. OP come non chiedi di rilevare se il dispositivo è guidato da un tocco o da un mouse, l'ho lasciato a un'altra persona per chiedere.
gestire sia
Mouse e eventi touch possono coesistere. L'aggiunta di ascoltatori per gli eventi del mouse o tocco su un dispositivo che non ne ha uno o l'altro non costituisce un problema. L'interfaccia di input mancante semplicemente non genera alcun evento. Ciò semplifica l'implementazione di una soluzione trasparente per la tua pagina.
Si tratta dell'interfaccia che preferisci ed emula quell'interfaccia quando l'hardware per esso non è disponibile. In questo caso, emulare il mouse da qualsiasi evento di tocco che viene creato.
Creazione di eventi a livello di programmazione.
Il codice utilizza l'oggetto MouseEvent per creare e inviare eventi. È semplice da usare e gli eventi sono indistinguibili dai veri eventi del mouse. Per una descrizione dettagliata di MouseEvents goto MDN MouseEvent
Alla sua base.
creare un evento clic del mouse e la spedizione al documento
var event = new MouseEvent("click", {'view': window, 'bubbles': true,'cancelable': true});
document.dispatchEvent(event);
È inoltre possibile inviare l'evento ai singoli elementi.
document.getElementById("someButton").dispatchEvent(event);
Per ascoltare l'evento è come ascoltare il mouse.
document.getElementById("someButton").addEventListener(function(event){
// your code
));
Il secondo argomento della funzione MouseEvent
è dove è possibile aggiungere informazioni supplementari sull'evento. Supponiamo ad esempio clientX
e clientY
la posizione del mouse o which
o buttons
per il quale pulsante/i viene premuto.
Se avete mai guardato il mouseEvent
saprete che ci sono un sacco di proprietà. Quindi, esattamente ciò che invii nell'evento del mouse dipenderà da ciò che il listener di eventi sta usando.
Toccare gli eventi.
Gli eventi di tocco sono simili al mouse. C'è touchstart
, touchmove
e touchend
. Differiscono nel fatto che forniscono una serie di posizioni, un elemento per ogni punto di contatto. Non sei sicuro di quale sia il massimo ma per questa risposta ci interessa solo uno. Vedi MDN touchEvent per i dettagli completi.
Quello che dobbiamo fare è per gli eventi di tocco che coinvolgono solo un punto di contatto che vogliamo generare eventi di mouse corrispondenti nella stessa posizione. Se l'evento di tocco restituisce più di un punto di contatto, non possiamo sapere su quale sia l'obiettivo previsto, quindi li ignoreremo semplicemente.
function touchEventHandler(event){
if (event.touches.length > 1){ // Ignor multi touch events
return;
}
}
Così ora sappiamo che il tocco di un singolo contatto che possiamo fare per creare gli eventi del mouse sulla base delle informazioni nel tocco eventi.
Nella sua forma più semplice
touch = event.changedTouches[0]; // get the position information
if(type === "touchmove"){
mouseEventType = "mousemove"; // get the name of the mouse event
// this touch will emulate
}else
if(type === "touchstart"){
mouseEventType = "mousedown"; // mouse event to create
}else
if(type === "touchend"){
mouseEventType = "mouseup"; // ignore mouse up if click only
}
var mouseEvent = new MouseEvent(// create event
mouseEventType, // type of event
{
'view': event.target.ownerDocument.defaultView,
'bubbles': true,
'cancelable': true,
'screenX':touch.screenX, // get the touch coords
'screenY':touch.screenY, // and add them to the
'clientX':touch.clientX, // mouse event
'clientY':touch.clientY,
});
// send it to the same target as the touch event contact point.
touch.target.dispatchEvent(mouseEvent);
Ora i vostri ascoltatori del mouse riceveranno mousedown
, mousemove
, mouseup
eventi quando un utente tocca il dispositivo in un solo punto.
Manca il clic
Tutto bene finora, ma c'è un evento del mouse mancante, che è necessario pure. "onClick" Non sono sicuro che ci sia un evento tattile equivoco e, proprio come esercizio, ho visto che ci sono abbastanza informazioni su ciò che dobbiamo decidere se un insieme di eventi tattili può essere considerato un clic.
Dipenderà da quanto distanti gli eventi di tocco iniziale e finale, più di pochi pixel e il suo trascinamento. Dipenderà anche da quanto tempo. (Anche se non è lo stesso di un mouse) trovo che le persone tendono a toccare per fare clic, mentre un mouse può essere tenuto, invece della conformazione sul rilascio, o trascinare per annullare, questo non è il modo in cui le persone usano l'interfaccia touch.
Così registro l'ora in cui si verifica l'evento touchStart. event.timeStamp
e da dove è iniziato. Quindi all'evento touchEnd
trovo la distanza che ha spostato e il tempo trascorso da. Se sono entrambi sotto i limiti che ho impostato, genererò anche un evento click del mouse insieme all'evento mouse up.
Questo è il modo di base per convertire gli eventi tattili in eventi del mouse.
po 'di codice
Qui di seguito è una piccola API chiamata mouseTouch che fa ciò che ho appena spiegato. Copre le interazioni di mouse più elementari richieste in una semplice applicazione di disegno.
// _______ _
// |__ __| | |
// _ __ ___ ___ _ _ ___ ___| | ___ _ _ ___| |__
// | '_ ` _ \/_ \| | |/__|/ _ \ |/ _ \| | | |/ __| '_ \
// | | | | | | (_) | |_| \__ \ __/ | (_) | |_| | (__| | | |
// |_| |_| |_|\___/ \__,_|___/\___|_|\___/ \__,_|\___|_| |_|
//
//
// Demonstration of a simple mouse emulation API using touch events.
// Using touch to simulate a mouse.
// Keeping it clean with touchMouse the only pubic reference.
// See Usage instructions at bottom.
var touchMouse = (function(){
"use strict";
var timeStart, touchStart, mouseTouch, listeningElement, hypot;
mouseTouch = {}; // the public object
// public properties.
mouseTouch.clickRadius = 3; // if touch start and end within 3 pixels then may be a click
mouseTouch.clickTime = 200; // if touch start and end in under this time in ms then may be a click
mouseTouch.generateClick = true; // if true simulates onClick event
// if false only generate mousedown, mousemove, and mouseup
mouseTouch.clickOnly = false; // if true on generate click events
mouseTouch.status = "Started."; // just for debugging
// ES6 new math function
// not sure the extent of support for Math.hypot so hav simple poly fill
if(typeof Math.hypot === 'function'){
hypot = Math.hypot;
}else{
hypot = function(x,y){ // Untested
return Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
};
}
// Use the new API and MouseEvent object
function triggerMouseEvemt(type,fromTouch,fromEvent){
var mouseEvent = new MouseEvent(
type,
{
'view': fromEvent.target.ownerDocument.defaultView,
'bubbles': true,
'cancelable': true,
'screenX':fromTouch.screenX,
'screenY':fromTouch.screenY,
'clientX':fromTouch.clientX,
'clientY':fromTouch.clientY,
'offsetX':fromTouch.clientX, // this is for old Chrome
'offsetY':fromTouch.clientY,
'ctrlKey':fromEvent.ctrlKey,
'altKey':fromEvent.altKey,
'shiftKey':fromEvent.shiftKey,
'metaKey':fromEvent.metaKey,
'button':0,
'buttons':1,
});
// to do.
// dispatch returns cancelled you will have to
// add code here if needed
fromTouch.target.dispatchEvent(mouseEvent);
}
// touch listener. Listens to Touch start, move and end.
// dispatches mouse events as needed. Also sends a click event
// if click falls within supplied thresholds and conditions
function emulateMouse(event) {
var type, time, touch, isClick, mouseEventType, x, y, dx, dy, dist;
event.preventDefault(); // stop any default happenings interfering
type = event.type ; // the type.
// ignore multi touch input
if (event.touches.length > 1){
if(touchStart !== undefined){ // don't leave the mouse down
triggerMouseEvent("mouseup",event.changedTouches[0],event);
}
touchStart = undefined;
return;
}
mouseEventType = "";
isClick = false; // default no click
// check for each event type I have the most numorus move event first, Good practice to always think about the efficancy for conditional coding.
if(type === "touchmove" && !mouseTouch.clickOnly){ // touchMove
touch = event.changedTouches[0];
mouseEventType = "mousemove"; // not much to do just move the mouse
}else
if(type === "touchstart"){
touch = touchStart = event.changedTouches[0]; // save the touch start for dist check
timeStart = event.timeStamp; // save the start time
mouseEventType = !mouseTouch.clickOnly?"mousedown":""; // mouse event to create
}else
if(type === "touchend"){ // end check time and distance
touch = event.changedTouches[0];
mouseEventType = !mouseTouch.clickOnly?"mouseup":""; // ignore mouse up if click only
// if click generator active
if(touchStart !== undefined && mouseTouch.generateClick){
time = event.timeStamp - timeStart; // how long since touch start
// if time is right
if(time < mouseTouch.clickTime){
// get the distance from the start touch
dx = touchStart.clientX-touch.clientX;
dy = touchStart.clientY-touch.clientY;
dist = hypot(dx,dy);
if(dist < mouseTouch.clickRadius){
isClick = true;
}
}
}
}
// send mouse basic events if any
if(mouseEventType !== ""){
// send the event
triggerMouseEvent(mouseEventType,touch,event);
}
// if a click also generates a mouse click event
if(isClick){
// generate mouse click
triggerMouseEvent("click",touch,event);
}
}
// remove events
function removeTouchEvents(){
listeningElement.removeEventListener("touchstart", emulateMouse);
listeningElement.removeEventListener("touchend", emulateMouse);
listeningElement.removeEventListener("touchmove", emulateMouse);
listeningElement = undefined;
}
// start adds listeners and makes it all happen.
// element is optional and will default to document.
// or will Listen to element.
function startTouchEvents(element){
if(listeningElement !== undefined){ // untested
// throws to stop cut and past useage of this example code.
// Overwriting the listeningElement can result in a memory leak.
// You can remove this condition block and it will work
// BUT IT IS NOT RECOGMENDED
throw new ReferanceError("touchMouse says!!!! API limits functionality to one element.");
}
if(element === undefined){
element = document;
}
listeningElement = element;
listeningElement.addEventListener("touchstart", emulateMouse);
listeningElement.addEventListener("touchend", emulateMouse);
listeningElement.addEventListener("touchmove", emulateMouse);
}
// add the start event to public object.
mouseTouch.start = startTouchEvents;
// stops event listeners and remove them from the DOM
mouseTouch.stop = removeTouchEvents;
return mouseTouch;
})();
// How to use
touchMouse.start(); // done using defaults will emulate mouse on the entier page
// For one element and only clicks
// HTML
<input value="touch click me" id="touchButton" type="button"></input>
// Script
var el = document.getElementById("touchButton");
if(el !== null){
touchMouse.clickOnly = true;
touchMouse.start(el);
}
// For drawing on a canvas
<canvas id="touchCanvas"></canvas>
// script
var el = document.getElementById("touchButton");
if(el !== null){
touchMouse.generateClick = false; // no mouse clicks please
touchMouse.start(el);
}
// For switching elements call stop then call start on the new element
// warning touchMouse retained a reference to the element you
// pass it with start. Dereferencing touchMouse will not delete it.
// Once you have called start you must call stop in order to delete it.
// API
//---------------------------------------------------------------
// To dereference call the stop method if you have called start . Then dereference touchMouse
// Example
touchMouse.stop();
touchMouse = undefined;
// Methods.
//---------------------------------------------------------------
// touchMouse.start(element); // element optional. Element is the element to attach listeners to.
// Calling start a second time without calling stop will
// throw a reference error. This is to stop memory leaks.
// YOU Have been warned...
// touchMouse.stop(); // removes listeners and dereferences any DOM objects held
//---------------------------------------------------------------
// Properties
// mouseTouch.clickRadius = 3; // Number. Default 3. If touch start and end within 3 pixels then may be a click
// mouseTouch.clickTime = 200; // Number. Default 200. If touch start and end in under this time in ms then may be a click
// mouseTouch.generateClick; // Boolean. Default true. If true simulates onClick event
// // if false only generate mousedown, mousemove, and mouseup
// mouseTouch.clickOnly; // Boolean. Default false. If true only generate click events Default false
// mouseTouch.status; // String. Just for debugging kinda pointless really.
Quindi spero che ti aiuti con il tuo codice.