que - javascript no funciona en ipad
Detecta el movimiento de un dedo a través de JavaScript en el iPhone y Android (15)
¿Has probado hammer.js? http://eightmedia.github.com/hammer.js/ También funciona en los teléfonos con Windows ...
¿Cómo puede detectar que un usuario pasó el dedo en alguna dirección en una página web con JavaScript?
Me preguntaba si habría una solución que funcionara para sitios web tanto en el iPhone como en un teléfono con Android.
Algunos mod de respuesta superior (no puedo comentar ...) para tratar con 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;
}
};
Basado en la respuesta de @givanse, esta es la forma de hacerlo con las 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 así:
// 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();
Ejemplo simple de código JS de vainilla:
document.addEventListener(''touchstart'', handleTouchStart, false);
document.addEventListener(''touchmove'', handleTouchMove, false);
var xDown = null;
var yDown = null;
function getTouches(evt) {
return evt.touches || // browser API
evt.originalEvent.touches; // jQuery
}
function handleTouchStart(evt) {
const firstTouch = getTouches(evt)[0];
xDown = firstTouch.clientX;
yDown = firstTouch.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.
Encontré este plugin jquery touchwipe que funciona en mi primera generación de iPod touch y mi droid increíbles. http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
He encontrado que la respuesta brillante de @givanse es la más confiable y compatible en múltiples navegadores móviles para registrar acciones de deslizamiento.
Sin embargo, hay un cambio en su código requerido para que funcione en los navegadores móviles modernos que usan jQuery
.
event.touches
no existirá si jQuery
se usa y da como resultado undefined
y debe reemplazarse por event.originalEvent.touches
. Sin jQuery
, event.touches
debería funcionar bien.
Entonces 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, UC Browser
- iOS : Safari, Chrome, UC Browser
He vuelto a empaquetar http://www.netcu.de/jquery-touchwipe-iphone-ipad-library como un pequeño complemento de jquery: github.com/marcandre/detect_swipe
Lo que he usado antes es que tienes que detectar el evento del ratón, registrar su ubicación x, y (lo que sea relevante), luego detectar el evento mouseup y restar los dos valores.
Si alguien está tratando de usar jQuery Mobile en Android y tiene problemas con la detección de deslizamiento JQM
(También tuve algunos en los teléfonos Xperia Z1, Galaxy S3, Nexus 4 y algunos Wiko). 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
}
Swipe en Android no se detectó a menos que fuera un golpe muy largo, preciso y rápido.
Con estas dos líneas funciona correctamente.
Si solo necesita deslizar, es mejor usar el tamaño solo con la parte que necesita. Esto debería funcionar en cualquier dispositivo táctil.
Esto es ~ 450 bytes ''después de la compresión, minificación, babel, etc. de gzip.
Escribí la siguiente clase basada en las otras respuestas, usa un porcentaje movido en lugar de píxeles y un patrón de dispatcher de eventos para enganchar / desenganchar cosas.
Úsalo así:
const dispatcher = new SwipeEventDispatcher(myElement);
dispatcher.on(''SWIPE_RIGHT'', () => { console.log(''I swiped right!'') })
export class SwipeEventDispatcher {
constructor(element, options = {}) {
this.evtMap = {
SWIPE_LEFT: [],
SWIPE_UP: [],
SWIPE_DOWN: [],
SWIPE_RIGHT: []
};
this.xDown = null;
this.yDown = null;
this.element = element;
this.options = Object.assign({ triggerPercent: 0.3 }, options);
element.addEventListener(''touchstart'', evt => this.handleTouchStart(evt), false);
element.addEventListener(''touchend'', evt => this.handleTouchEnd(evt), false);
}
on(evt, cb) {
this.evtMap[evt].push(cb);
}
off(evt, lcb) {
this.evtMap[evt] = this.evtMap[evt].filter(cb => cb !== lcb);
}
trigger(evt, data) {
this.evtMap[evt].map(handler => handler(data));
}
handleTouchStart(evt) {
this.xDown = evt.touches[0].clientX;
this.yDown = evt.touches[0].clientY;
}
handleTouchEnd(evt) {
const deltaX = evt.changedTouches[0].clientX - this.xDown;
const deltaY = evt.changedTouches[0].clientY - this.yDown;
const distMoved = Math.abs(Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : deltaY);
const activePct = distMoved / this.element.offsetWidth;
if (activePct > this.options.triggerPercent) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
deltaX < 0 ? this.trigger(''SWIPE_LEFT'') : this.trigger(''SWIPE_RIGHT'');
} else {
deltaY > 0 ? this.trigger(''SWIPE_UP'') : this.trigger(''SWIPE_DOWN'');
}
}
}
}
export default SwipeEventDispatcher;
Tuve problemas con el controlador de touchend disparando continuamente mientras el usuario estaba arrastrando un dedo. No sé si eso se debe a algo que estoy haciendo mal o no, pero lo modifiqué para acumular movimientos con touchmove y touchend en realidad dispara la devolución de llamada.
También necesitaba tener un gran número de estas instancias, por lo que agregué métodos de habilitar / deshabilitar.
Y un umbral donde no se dispara un golpe corto. Touchstart cero es los contadores cada vez.
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);
}
}
}
}
Utiliza dos:
jQuery mobile: funciona en la mayoría de los casos y especialmente cuando está desarrollando una aplicación que usa otro complemento de jQuery que mejor usar los controles móviles de jQuery para esto. Visítelo aquí: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp
Hora del martillo ! Una de las bibliotecas basadas en javascript mejores, ligeras y rápidas. Visítelo aquí: https://hammerjs.github.io/
jQuery Mobile también incluye soporte de swipe: http://api.jquerymobile.com/swipe/
Ejemplo
$("#divId").on("swipe", function(event) {
alert("It''s a swipe!");
});
trashold, timeout swipe, swipeBlockElems agregar.
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;
}
CustomEvent algunas de las respuestas aquí en un script que usa CustomEvent para disparar eventos CustomEvent en el DOM. Agregue la secuencia de comandos pure-swipe.min.js a su página y escuche los eventos deslizados :
deslizar hacia la izquierda
document.addEventListener(''swiped-left'', function(e) {
console.log(e.target); // the element that was swiped
});
biriendo a la derecha
document.addEventListener(''swiped-right'', function(e) {
console.log(e.target); // the element that was swiped
});
barrido
document.addEventListener(''swiped-up'', function(e) {
console.log(e.target); // the element that was swiped
});
deslizado hacia abajo
document.addEventListener(''swiped-down'', function(e) {
console.log(e.target); // the element that was swiped
});
También puede adjuntar directamente a un elemento:
document.getElementById(''myBox'').addEventListener(''swiped-down'', function(e) {
console.log(e.target); // the element that was swiped
});
Configuración opcional
Puede especificar los siguientes atributos para ajustar cómo funciona la interacción de deslizamiento en su página (estos son opcionales) .
<div data-swipe-threshold="10"
data-swipe-timeout="1000"
data-swipe-ignore="false">
Swiper, get swiping!
</div>
El código fuente está disponible en Github