Detectar un dedo deslizar a través de JavaScript en el iPhone y Android
¿Cómo se puede detectar que un usuario pasó su dedo en alguna dirección sobre una página web con JavaScript?
Me preguntaba si había una solución que trabajaría para los Web site en el iPhone y un teléfono androide.
- ¿Cómo acceder a `this` dentro de un renderRow de un ListView?
- Extracto de Android WebView HTML
- ¿Cómo podemos ejecutar una función javascript y obtener un valor de retorno en nuestra aplicación android?
- Ignorar el certificado SSL Comprobar en Android React Native
- JavaScript se detiene en la pestaña inactiva de Chrome de Android
- Html5 video no se reproduce en android webview, pero funciona en (móvil) cromo
- Android webview + javascript no mostrar la salida en android 4.0.x, 3.x
- JavaScript no funciona en Android WebView
- Activar evento de clic en la etiqueta de enlace en JS para Android e iPhone
- IPhone WebApp en la pantalla de inicio Persistencia
- Tipo de error 3. La clase de actividad {com.awesome_project / com.awesome_project.MainActivity} no existe en react native (dispositivo Android)
- ¿Cómo mostrar la página de contenido Html sabia usando webview en android?
- Android cómo mostrar PopupMenu en webview como GMail
Ejemplo de código simple de la vainilla JS:
document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); var xDown = null; var yDown = null; function handleTouchStart(evt) { xDown = evt.touches[0].clientX; yDown = evt.touches[0].clientY; }; function handleTouchMove(evt) { if ( ! xDown || ! yDown ) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; var xDiff = xDown - xUp; var yDiff = yDown - yUp; if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) { /* left swipe */ } else { /* right swipe */ } } else { if ( yDiff > 0 ) { /* up swipe */ } else { /* down swipe */ } } /* reset values */ xDown = null; yDown = null; };
Probado en Android.
Utilice evt.originalEvent.touches
lugar de evt.touches
si está trabajando con JQuery.
He encontrado este plugin jquery touchwipe que funciona tanto en mi primera generación de ipod touch y mi droide increíble. http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
¿Has probado hammer.js? http://eightmedia.github.com/hammer.js/ También funciona en Windows Phones ..
Lo que he usado antes es que tienes que detectar el evento mousedown, grabar su ubicación x, y (lo que sea relevante) y luego detectar el evento mouseup, y restar los dos valores.
JQuery Mobile también incluye soporte de swipe: http://api.jquerymobile.com/swipe/
Ejemplo
$("#divId").on("swipe", function(event) { alert("It's a swipe!"); });
Basado en la respuesta de @ givanse, esto es cómo usted podría hacerlo con classes
:
class Swipe { constructor(element) { this.xDown = null; this.yDown = null; this.element = typeof(element) === 'string' ? document.querySelector(element) : element; this.element.addEventListener('touchstart', function(evt) { this.xDown = evt.touches[0].clientX; this.yDown = evt.touches[0].clientY; }.bind(this), false); } onLeft(callback) { this.onLeft = callback; return this; } onRight(callback) { this.onRight = callback; return this; } onUp(callback) { this.onUp = callback; return this; } onDown(callback) { this.onDown = callback; return this; } handleTouchMove(evt) { if ( ! this.xDown || ! this.yDown ) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; this.xDiff = this.xDown - xUp; this.yDiff = this.yDown - yUp; if ( Math.abs( this.xDiff ) > Math.abs( this.yDiff ) ) { // Most significant. if ( this.xDiff > 0 ) { this.onLeft(); } else { this.onRight(); } } else { if ( this.yDiff > 0 ) { this.onUp(); } else { this.onDown(); } } // Reset values. this.xDown = null; this.yDown = null; } run() { this.element.addEventListener('touchmove', function(evt) { this.handleTouchMove(evt).bind(this); }.bind(this), false); } }
Puedes usarlo de esta manera:
// Use class to get element by string. var swiper = new Swipe('#my-element'); swiper.onLeft(function() { alert('You swiped left.') }); swiper.run(); // Get the element yourself. var swiper = new Swipe(document.getElementById('#my-element')); swiper.onLeft(function() { alert('You swiped left.') }); swiper.run(); // One-liner. (new Swipe('#my-element')).onLeft(function() { alert('You swiped left.') }).run();
He encontrado @givanse brillante respuesta para ser el más fiable y compatible a través de múltiples navegadores móviles para el registro de acciones de deslizamiento.
Sin embargo, hay un cambio en su código necesario para que funcione en los navegadores móviles de hoy en día que utilizan jQuery
.
event.touches
no existirá si jQuery
se utiliza y resulta en undefined
y debe ser reemplazado por event.originalEvent.touches
. Sin jQuery
, event.touches
debería funcionar bien.
Así que la solución se convierte,
document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); var xDown = null; var yDown = null; function handleTouchStart(evt) { xDown = evt.originalEvent.touches[0].clientX; yDown = evt.originalEvent.touches[0].clientY; }; function handleTouchMove(evt) { if ( ! xDown || ! yDown ) { return; } var xUp = evt.originalEvent.touches[0].clientX; var yUp = evt.originalEvent.touches[0].clientY; var xDiff = xDown - xUp; var yDiff = yDown - yUp; if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) { /* left swipe */ } else { /* right swipe */ } } else { if ( yDiff > 0 ) { /* up swipe */ } else { /* down swipe */ } } /* reset values */ xDown = null; yDown = null; };
Probado en:
- Android : Chrome, navegador de UC
- IOS : Safari, Chrome, Navegador de UC
He reempaquetado TouchWipe
como un complemento jquery corto: detectSwipe
Algunos mod de uppest respuesta (no puedo comentar …) para hacer frente a golpes cortos
document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); var xDown = null; var yDown = null; function handleTouchStart(evt) { xDown = evt.touches[0].clientX; yDown = evt.touches[0].clientY; }; function handleTouchMove(evt) { if ( ! xDown || ! yDown ) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; var xDiff = xDown - xUp; var yDiff = yDown - yUp; if(Math.abs( xDiff )+Math.abs( yDiff )>150){ //to deal with to short swipes if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) {/* left swipe */ alert('left!'); } else {/* right swipe */ alert('right!'); } } else { if ( yDiff > 0 ) {/* up swipe */ alert('Up!'); } else { /* down swipe */ alert('Down!'); } } /* reset values */ xDown = null; yDown = null; } };
Trashold, swap de tiempo de espera, swipeBlockElems add.
document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); document.addEventListener('touchend', handleTouchEnd, false); const SWIPE_BLOCK_ELEMS = [ 'swipBlock', 'handle', 'drag-ruble' ] let xDown = null; let yDown = null; let xDiff = null; let yDiff = null; let timeDown = null; const TIME_TRASHOLD = 200; const DIFF_TRASHOLD = 130; function handleTouchEnd() { let timeDiff = Date.now() - timeDown; if (Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/ if (Math.abs(xDiff) > DIFF_TRASHOLD && timeDiff < TIME_TRASHOLD) { if (xDiff > 0) { // console.log(xDiff, TIME_TRASHOLD, DIFF_TRASHOLD) SWIPE_LEFT(LEFT) /* left swipe */ } else { // console.log(xDiff) SWIPE_RIGHT(RIGHT) /* right swipe */ } } else { console.log('swipeX trashhold') } } else { if (Math.abs(yDiff) > DIFF_TRASHOLD && timeDiff < TIME_TRASHOLD) { if (yDiff > 0) { /* up swipe */ } else { /* down swipe */ } } else { console.log('swipeY trashhold') } } /* reset values */ xDown = null; yDown = null; timeDown = null; } function containsClassName (evntarget , classArr) { for (var i = classArr.length - 1; i >= 0; i--) { if( evntarget.classList.contains(classArr[i]) ) { return true; } } } function handleTouchStart(evt) { let touchStartTarget = evt.target; if( containsClassName(touchStartTarget, SWIPE_BLOCK_ELEMS) ) { return; } timeDown = Date.now() xDown = evt.touches[0].clientX; yDown = evt.touches[0].clientY; xDiff = 0; yDiff = 0; } function handleTouchMove(evt) { if (!xDown || !yDown) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; xDiff = xDown - xUp; yDiff = yDown - yUp; }
Si alguien está intentando utilizar jQuery Mobile en Android y tiene problemas con la detección de deslizamiento JQM
(Tuve algunos en Xperia Z1, Galaxy S3, Nexus 4 y algunos teléfonos Wiko también) esto puede ser útil:
//Fix swipe gesture on android if(android){ //Your own device detection here $.event.special.swipe.verticalDistanceThreshold = 500 $.event.special.swipe.horizontalDistanceThreshold = 10 }
No se detectó Android en Android, a menos que fuera un golpe muy largo, preciso y rápido.
Con estas dos líneas funciona correctamente
Dos usados:
JQuery móvil: el trabajo en la mayoría de los casos y especialmente cuando se está desarrollando applicaion que utiliza otro plugin jQuery entonces mejor utilizar jQuery controles móviles para esto. Visite aquí: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp
Hora del martillo ! Una de las mejores, ligeras y rápidas bibliotecas basadas en javascript. Visite aquí: https://hammerjs.github.io/
Tuve problemas con el manipulador touchend disparando continuamente mientras el usuario estaba arrastrando un dedo alrededor. No sé si eso es debido a algo que estoy haciendo mal o no, pero lo rewired esto para acumular movimientos con touchmove y touchend realmente dispara la devolución de llamada.
También necesité tener un número grande de estos casos y así que agregué habilitar / deshabilitar métodos.
Y un umbral en el que no se dispara un golpe corto. Toque el cero con los contadores cada vez.
Usted puede cambiar el target_node sobre la marcha. Habilitar en la creación es opcional.
/** Usage: */ touchevent = new Modules.TouchEventClass(callback, target_node); touchevent.enable(); touchevent.disable(); /** * * Touch event module * * @param method set_target_mode * @param method __touchstart * @param method __touchmove * @param method __touchend * @param method enable * @param method disable * @param function callback * @param node target_node */ Modules.TouchEventClass = class { constructor(callback, target_node, enable=false) { /** callback function */ this.callback = callback; this.xdown = null; this.ydown = null; this.enabled = false; this.target_node = null; /** move point counts [left, right, up, down] */ this.counts = []; this.set_target_node(target_node); /** Enable on creation */ if (enable === true) { this.enable(); } } /** * Set or reset target node * * @param string/node target_node * @param string enable (optional) */ set_target_node(target_node, enable=false) { /** check if we're resetting target_node */ if (this.target_node !== null) { /** remove old listener */ this.disable(); } /** Support string id of node */ if (target_node.nodeName === undefined) { target_node = document.getElementById(target_node); } this.target_node = target_node; if (enable === true) { this.enable(); } } /** enable listener */ enable() { this.enabled = true; this.target_node.addEventListener("touchstart", this.__touchstart.bind(this)); this.target_node.addEventListener("touchmove", this.__touchmove.bind(this)); this.target_node.addEventListener("touchend", this.__touchend.bind(this)); } /** disable listener */ disable() { this.enabled = false; this.target_node.removeEventListener("touchstart", this.__touchstart); this.target_node.removeEventListener("touchmove", this.__touchmove); this.target_node.removeEventListener("touchend", this.__touchend); } /** Touchstart */ __touchstart(event) { event.stopPropagation(); this.xdown = event.touches[0].clientX; this.ydown = event.touches[0].clientY; /** reset count of moves in each direction, [left, right, up, down] */ this.counts = [0, 0, 0, 0]; } /** Touchend */ __touchend(event) { let max_moves = Math.max(...this.counts); if (max_moves > 500) { // set this threshold appropriately /** swipe happened */ let index = this.counts.indexOf(max_moves); if (index == 0) { this.callback("left"); } else if (index == 1) { this.callback("right"); } else if (index == 2) { this.callback("up"); } else { this.callback("down"); } } } /** Touchmove */ __touchmove(event) { event.stopPropagation(); if (! this.xdown || ! this.ydown) { return; } let xup = event.touches[0].clientX; let yup = event.touches[0].clientY; let xdiff = this.xdown - xup; let ydiff = this.ydown - yup; /** Check x or y has greater distance */ if (Math.abs(xdiff) > Math.abs(ydiff)) { if (xdiff > 0) { this.counts[0] += Math.abs(xdiff); } else { this.counts[1] += Math.abs(xdiff); } } else { if (ydiff > 0) { this.counts[2] += Math.abs(ydiff); } else { this.counts[3] += Math.abs(ydiff); } } } }