w3schools touchend eventos event changedtouches javascript javascript-events

javascript - eventos - touchend



¿Cómo saber el evento real. Objetivo del evento javascript de touchmove? (4)

Así que los eventos táctiles tienen diferentes "filosofías" cuando se trata de cómo interactúan:

  • Ratón se mueve = "hover" como comportamiento
  • Toque se mueve = "arrastra" como comportamiento

Esta diferencia proviene del hecho de que no puede haber un evento de movimiento táctil sin un inicio táctil que lo preceda, ya que el usuario tiene que tocar la pantalla para iniciar esta interacción. Con el mouse, por supuesto, un usuario puede mover el mouse por toda la pantalla sin presionar nunca el botón (evento de mousedown)

Esta es la razón por la que básicamente no podemos esperar usar cosas como los efectos de desplazamiento con el tacto:

element:hover { background-color: yellow; }

Y es por eso que cuando el usuario toca la pantalla con 1 dedo, el primer evento (touchstart) adquiere el elemento objetivo y los eventos subsiguientes (touchmove) mantendrán la referencia al elemento original donde se inició el toque. Se siente mal, pero existe la lógica de que es posible que también necesite información de destino original. Por lo tanto, lo ideal sería que en el futuro estuvieran disponibles (objetivo de origen y objetivo actual).

Por lo tanto, la práctica común de hoy (2018) donde las pantallas se pueden colocar con el mouse Y tocar al mismo tiempo todavía es unir a los dos oyentes (mouse y touch) y luego "normalizar" las coordenadas del evento y usar el api del navegador mencionado anteriormente para encontrar el elemento en esas coordenadas:

// get coordinates depending on pointer type: var xcoord = event.touches? event.touches[0].pageX : event.pageX; var ycoord = event.touches? event.touches[0].pageY : event.pageY; // get element in coordinates: var targetElement = document.elementFromPoint(xcoord, ycoord); // validate if this is a valid element for our case: if (targetElement && targetElement.classList.contains("dropZone")) { }

Estoy intentando desarrollar una interfaz de usuario de arrastrar / soltar simple en mi aplicación web. Un elemento se puede arrastrar con un mouse o un dedo y luego se puede colocar en una de varias zonas de arrastre. Cuando un elemento se arrastra sobre una zona de arrastre (pero aún no está liberado), esa zona se resalta, marcando la ubicación de aterrizaje seguro. Eso funciona perfectamente bien con los eventos del mouse, pero estoy atascado con la familia touchstart / touchmove / touchend en el iPhone / iPad.

El problema es que cuando se llama al controlador de eventos onuchmove de un elemento, su event.touches[0].target siempre apunta al elemento HTML de origen (el elemento) y no al elemento que se encuentra actualmente bajo el dedo. Además, cuando un elemento se arrastra con el dedo sobre alguna zona de touchmove no se llama en absoluto a los propios manejadores de touchmove esa zona de touchmove . Básicamente, eso significa que no puedo determinar cuándo un dedo está sobre cualquiera de las zonas de arrastre y, por lo tanto, no puedo resaltarlos según sea necesario. Al mismo tiempo, cuando se usa un mouse, el botón mousedown se dispara correctamente para todos los elementos HTML debajo del cursor.

Algunas personas confirman que se supone que funciona así, por ejemplo, http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/ : Para aquellos de ustedes que vienen de En el mundo normal del diseño web, en un evento normal de mousemove, el nodo que se pasa en el atributo de destino suele ser lo que el mouse ha superado. Pero en todos los eventos táctiles de iPhone, el objetivo es una referencia al nodo de origen.

Pregunta: ¿hay alguna manera de determinar el elemento real bajo un dedo (NO el elemento inicialmente tocado que puede ser diferente en muchas circunstancias)?


Ciertamente no es así como se supone que funcionan los objetivos de evento. Sin embargo, otra inconsistencia de DOM con la que probablemente ahora estamos atrapados para siempre, debido a que un proveedor viene con extensiones detrás de puertas cerradas sin ninguna revisión.

Utilice document.elementFromPoint para solucionarlo.

document.elementFromPoint(event.clientX, event.clientY);


He encontrado el mismo problema en Android (WebView + Phonegap). Quiero poder arrastrar elementos alrededor y detectar cuándo se están arrastrando sobre otro elemento determinado. Por alguna razón, los eventos táctiles parecen ignorar el valor del atributo pointer-events .

Ratón:

  • si se establece pointer-events="visiblePainted" , event.target apuntará al elemento arrastrado.
  • si pointer-events="none" está establecido, event.target apuntará al elemento debajo del elemento arrastrado (mi zona de arrastre)

Así es como se supone que funcionan las cosas y por qué tenemos el atributo pointer-events en primer lugar.

Toque:

  • event.target siempre apunta al elemento arrastrado, independientemente del valor de pointer-events que está IMHO equivocado.

Mi solución es crear mi propio objeto de evento de arrastre (una interfaz común para los eventos del mouse y táctil) que contiene las coordenadas del evento y el objetivo:

  • para eventos de mouse simplemente reutilizo el evento de mouse tal como está
  • para el evento táctil que uso:

    DragAndDrop.prototype.getDragEventFromTouch = function (event) { var touch = event.touches.item(0); return { screenX: touch.screenX, screenY: touch.screenY, clientX: touch.clientX, clientY: touch.clientY, pageX: touch.pageX, pageY: touch.pageY, target: document.elementFromPoint(touch.screenX, touch.screenY) }; };

Y luego úselo para procesar (verificando si el objeto arrastrado está en mi zona de arrastre). Por alguna razón, document.elementFromPoint() parece respetar el valor de pointer-events incluso en Android.


La respuesta aceptada de 2010 ya no funciona: touchmove no tiene un atributo clientX o clientY . (Supongo que solía hacerlo ya que la respuesta tiene un número de upvotes, pero no lo hace actualmente).

La solución actual es:

var myLocation = event.originalEvent.changedTouches[0]; var realTarget = document.elementFromPoint(myLocation.clientX, myLocation.clientY);

Probado y trabaja en:

  • Safari en iOS
  • Chrome en iOS
  • Chrome en Android
  • Chrome en el escritorio de Windows con capacidad táctil
  • FF en el escritorio de Windows con capacidad táctil

NO funciona en:

  • IE en el escritorio de Windows con capacidad táctil

No probado en:

  • Telefono windows