2013-01-18 9 views
11

Quindi, ho riscontrato un problema interessante mentre lavoravo a un'applicazione Web per Microsoft Surface.Ascolto di mouse e touchstart su dispositivi che utilizzano touch e mouse (ad esempio Surface)

Desidero aggiungere listener di eventi per quando un utente interagisce con un elemento DOM. Ora posso fare:

if ('ontouchstart' in document.documentElement) { 
    //Attach code for touch event listeners 
    document.addEventListener("touchstart" myFunc, false); 
} else { 
    //Attach code for mouse event listeners 
    document.addEventListener("mousedown" myFunc, false); 
} 

Se il dispositivo non ha un input del mouse, questo problema sarebbe semplice e il codice sopra funzionerebbe perfettamente. Ma Surface (e molti nuovi computer Windows 8) hanno ENTRAMBI un tocco e l'input del mouse. Quindi il codice sopra funzionerebbe solo quando l'utente ha toccato il dispositivo. Gli ascoltatori di eventi del mouse non verrebbero mai collegati.

Allora ho pensato, beh, avrei potuto fare questo:

if ('ontouchstart' in document.documentElement) { 
    //Attach code for touch event listeners 
    document.addEventListener("touchstart" myFunc, false); 
} 
//Always attach code for mouse event listeners 
document.addEventListener("mousedown" myFunc, false); 

dispositivi che non supportano tocco non avrebbe gli eventi collegati, ma un dispositivo che utilizza tocco registrerà i suoi gestori. Il problema di questo è però che myFunc() sarà chiamato due volte su un dispositivo touch:

  1. myFunc() sparerà quando "TouchStart" è sollevata
  2. Poiché i browser tocco tipicamente passano attraverso il ciclo TouchStart ->touchmove ->touchend ->mousedown ->mousemove ->mouseup ->click, myFunc() sarà chiamato di nuovo in "MouseDown"

Ho considerato l'aggiunta di codice a myFunc() tale che chiama e.preventDefault() ma questo sembra bloccare anche touchend così come mousedown/mousemove/mouseup su alcuni browser (link).

Odio fare sniffer useragent, ma sembra che i touch browser abbiano variazioni sul modo in cui vengono implementati gli eventi touch.

Mi manca qualcosa perché sembra che sicuramente queste implementazioni di JavaScript siano state decise con la possibilità di un browser che supporta sia mouse che touch!

+0

Che cosa ha a che fare questo con Android, considerando che Surface non esegue Android? – CommonsWare

+0

@CommonsWare - La mia domanda è pertinente a tutti i dispositivi touch che supportano anche un mouse, quindi sembra applicabile a Windows 8 e Android. – userx

+0

Sì, che dire di chromeOS? –

risposta

-3

Modificato: Se si utilizza jQuery, si sarà in grado di fare in questo modo:

var clickEventType=((document.ontouchstart!==null)?'mousedown':'touchstart'); 

$("a").bind(clickEventType, function() { 
    //Do something 
}); 

Questa scatterà solo uno degli eventi del bind.

trovate qui: How to bind 'touchstart' and 'click' events but not respond to both?

+1

Questo non risolve il problema. Semplicemente attacca i gestori per entrambi gli eventi e come tale non credo impedisca la possibilità che gli eventi ENTRAMBI si attivino (e quindi la funzione allegata si attiva due volte). – userx

+0

Sei corretto –

0

All'interno myFunc, controllare il tipo di evento. Se è touchstart, quindi fare e.stopPropagation().

function myFunc(e) { 
    if (e.type === 'touchstart') { 
     e.stopPropagation(); 
    } 
    //the rest of your code here 
} 
+0

Questo purtroppo non funziona neanche perché potrebbe essere un evento "mousedown" su un laptop Windows 8 che ha sia un mouse che un touch screen. – userx

+0

Modificato la mia risposta. – noypiscripter

2

Per Windows 8 è possibile utilizzare l'evento "MSPointerDown".

if (window.navigator.msPointerEnabled) { 
    document.addEventListener("MSPointerDown" myFunc, false); 
} 

aggiungere anche la seguente al vostro stile:

html { 
    -ms-touch-action: none; /* Direct all pointer events to JavaScript code. */ 
    } 

Vedi http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx per maggiori informazioni.

+0

potrebbe disabilitare lo scorrimento –