El problema de desplazamiento del iPad / iPhone hace que el usuario haga doble clic en un enlace

125

Tengo algunos sitios web que construí hace tiempo, que usan eventos de jquery mouse ... Acabo de recibir un ipad y noté que todos los eventos de mouse sobre se traducen en clics ... así que, por ejemplo, tengo que hacer dos clics en lugar de uno .. (el primer desplazamiento, que el clic real)

¿Hay alguna solución lista para resolver esto? tal vez un comando jquery que debería haber utilizado en lugar de pasar el mouse / out, etc.

Francesco
fuente
1
¿a qué están obligados tus eventos? por ejemplo, los eventos onclick deberían funcionar bien ... onmouseover, onmouseout y CSS: hover son los que son un poco difíciles de manejar ya que no hay "hover" disponible para una pantalla táctil. ¿Tienes una muestra de código?
scunliffe
Una cosa que sugeriría que haga es repensar su interfaz si es posible. la interacción en el ipad / iphone no refleja exactamente la de una PC, y probablemente sea una buena idea hacer que su sitio web se sienta como si estuviera escrito para el ipad / iphone / otros dispositivos táctiles con mecanismos multitáctiles similares. Solo un pensamiento.
jer
Estoy de acuerdo con "jer". Esta es una pregunta extraña, no creo que la solución aquí sea una "solución" personalmente. Creo que tiene sentido traducir un "desplazamiento del mouse" en un navegador de escritorio a un "toque de dedo" en un navegador con pantalla táctil. Si está de acuerdo con esa traducción, pero quiere un toque en lugar de dos, entonces probablemente haría una detección de funciones para los eventos de iPad (por ejemplo, "inicio táctil") y cambiaría los controladores de eventos. Tal vez extraiga su código en un tipo de funcionalidad "toque o haga clic" del complemento jquery que se activa de manera diferente según las características, pero me parece específico de su sitio web / aplicación.
Andy Atkinson
1
De hecho, considero que esta traducción es una característica. Si ha configurado los eventos de desplazamiento, debe haber alguna utilidad para verlos. Un solo toque revela un elemento suspendido, un segundo toque sigue el enlace "detrás" del elemento emergente.
Aaron

Respuestas:

205

No lo he probado completamente, pero dado que iOS dispara eventos táctiles, esto podría funcionar, suponiendo que esté en una configuración de jQuery.

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

La idea es que Mobile WebKit active un touchendevento al final de un toque, por lo que escuchamos eso y luego redirigimos el navegador tan pronto como touchendse haya activado un evento en un enlace.

cduruk
fuente
17
¿Dónde está mi generosidad? : P
cduruk
2
Paciencia, Padwan. SO dijo que tarda 24 horas en surtir efecto.
Andrew Hedges
2
A partir de jQuery 1.7, .onse prefiere .live. Después de leer esta respuesta, descubrí que cambiar mi código $('a').on('click touchend', function(e) {...})funciona de manera excelente.
Blazemonger
23
Bueno, esto resuelve el problema inicial, pero crea uno nuevo: al deslizar sobre se hace clic. Esta no es una solución.
luksak
9
Esto tiene sus defectos. Si hace clic en un enlace target="_blank", se abrirá en la misma ventana Y en una nueva ventana.
rybo111
37

No está del todo claro cuál es su pregunta, pero si solo desea eliminar el doble clic, mientras mantiene el efecto de desplazamiento del mouse, mi consejo es:

  • Añadir efectos de desplazamiento sobre touchstarty mouseenter.
  • Eliminar los efectos de desplazamiento sobre mouseleave, touchmovey click.

Antecedentes

Para simular un mouse, los navegadores como Webkit mobile activan los siguientes eventos si un usuario toca y suelta un dedo en la pantalla táctil (como iPad) (fuente: Touch And Mouse en html5rocks.com):

  1. touchstart
  2. touchmove
  3. touchend
  4. 300 ms de retraso, donde el navegador se asegura de que esto sea un solo toque, no un doble toque
  5. mouseover
  6. mouseenter
    • Nota : Si una mouseover, mouseentero mousemoveacontecimiento cambia el contenido de la página, los siguientes eventos no son despedidos.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

No parece posible decirle simplemente al navegador web que omita los eventos del mouse.

Lo que es peor, si un evento de mouseover cambia el contenido de la página, el evento de clic nunca se activa, como se explica en la Guía de contenido web de Safari - Manejo de eventos , en particular la figura 6.4 en Eventos de un dedo . Lo que es exactamente un "cambio de contenido" dependerá del navegador y la versión. Descubrí que para iOS 7.0, un cambio en el color de fondo no es (¿o ya no?) Un cambio de contenido.

Solución explicada

Recordar:

  • Añadir efectos de desplazamiento sobre touchstarty mouseenter.
  • Eliminar los efectos de desplazamiento sobre mouseleave, touchmovey click.

Tenga en cuenta que no hay acción en touchend!

Esto claramente funciona para eventos de mouse: mouseentery mouseleave(versiones ligeramente mejoradas de mouseovery mouseout) se disparan, y agregan y eliminan el cursor.

Si el usuario realmente tiene clickun enlace, el efecto de desplazamiento también se elimina. Esto garantiza que se elimine si el usuario presiona el botón Atrás en el navegador web.

Esto también funciona para eventos táctiles: en touchstartel efecto de desplazamiento se agrega. Se '' 'no' '' se eliminó el touchend. Se agrega nuevamente mouseentery, dado que esto no causa cambios en el contenido (ya se agregó), el clickevento también se activa y se sigue el enlace sin necesidad de que el usuario haga clic nuevamente.

El retraso de 300 ms que tiene un navegador entre un touchstartevento y clickrealmente se usa bien porque el efecto de desplazamiento se mostrará durante este corto tiempo.

Si el usuario decide cancelar el clic, un movimiento del dedo lo hará de la forma habitual. Normalmente, esto es un problema ya que no mouseleavese dispara ningún evento y el efecto de desplazamiento permanece en su lugar. Afortunadamente, esto se puede solucionar fácilmente eliminando el efecto de desplazamiento touchmove.

¡Eso es!

Tenga en cuenta que es posible eliminar el retraso de 300 ms , por ejemplo, utilizando la biblioteca FastClick , pero esto está fuera del alcance de esta pregunta.

Soluciones alternativas

He encontrado los siguientes problemas con las siguientes alternativas:

  • detección del navegador: extremadamente propenso a errores. Asume que un dispositivo tiene mouse o touch, mientras que una combinación de ambos se volverá cada vez más común cuando touch muestre prolifirate.
  • Detección de medios CSS: la única solución solo CSS que conozco. Aún propenso a errores, y aún asume que un dispositivo tiene mouse o touch, mientras que ambos son posibles.
  • Emule el evento de clic en touchend: Esto seguirá incorrectamente el enlace, incluso si el usuario solo desea desplazarse o hacer zoom, sin la intención de hacer clic en el enlace.
  • Use una variable para suprimir los eventos del mouse: esto establece una variable touchendque se usa como condición if en eventos posteriores del mouse para evitar cambios de estado en ese momento. La variable se restablece en el evento click. Esta es una solución decente si realmente no desea un efecto de desplazamiento en las interfaces táctiles. Desafortunadamente, esto no funciona si touchendse dispara a por otra razón y no se dispara ningún evento de clic (por ejemplo, el usuario se desplaza o hace zoom), y posteriormente intenta seguir el enlace con un mouse (es decir, en un dispositivo con mouse e interfaz táctil) )

Otras lecturas

Consulte también el problema de doble clic del iPad / iPhone y Desactivar los efectos de desplazamiento en los navegadores móviles .

MacFreek
fuente
2
parece ser la mejor explicación para aquellos que quieren más que una solución exacta del problema. Gracias
antijugador
Un agradecimiento especial por la información sobre el color de fondo para> iOS7. Pasé un tiempo tratando de averiguar cuándo comenzó a funcionar.
staffang
20

Parece que hay una solución CSS después de todo. La razón por la que Safari espera un segundo toque es por la imagen de fondo (o elementos) que generalmente asigna en el evento: hover. Si no se muestra ninguno, no tendrá ningún problema. La solución es apuntar a la plataforma iOS con un archivo CSS secundario (o estilo en el caso de un enfoque JS) que anula: desplazar el fondo para heredar, por ejemplo, y mantener ocultos los elementos que iba a mostrar al pasar el mouse:

Aquí hay un ejemplo de CSS y HTML: un bloque de producto con una etiqueta destacada al pasar el mouse:

HTML:

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS:

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

Solución (CSS secundario):

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}
Pavel Bogatinov
fuente
Esta respuesta está orientada a las imágenes de fondo, pero ¿tiene una solución para los cambios simples de opacidad? Esta solución no funciona para esto.
Ian S
5

No hay necesidad de hacer demasiado complicado.

$('a').on('touchend', function() {
    $(this).click();
});
Jsonras
fuente
5

Lo que funcionó para mí es lo que otros aquí ya han dicho:

No mostrar / ocultar elementos al pasar el mouse o mover el mouse (que es el evento en mi caso).

Esto es lo que dice Apple ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ):

Un elemento en el que se puede hacer clic es un enlace, un elemento de formulario, un área de mapa de imagen o cualquier otro elemento con controladores de mousemove, mousedown, mouseup o onclick

Si el usuario toca un elemento en el que se puede hacer clic, los eventos llegan en este orden: mouseover, mousemove, mousedown, mouseup y click. Además, si el contenido de la página cambia en el evento mousemove, no se envían eventos posteriores en la secuencia. Este comportamiento permite al usuario aprovechar el nuevo contenido.

Por lo tanto, podría usar la solución de @ woop: detectar el UserAgent, verificar si es un dispositivo iOS y luego vincular el evento. Terminé usando esta técnica porque se adapta a mis necesidades y tiene más sentido no vincular eventos de desplazamiento cuando no lo desee.

Pero ... si no quiere meterse con UserAgents y aún así ocultar / mostrar elementos en hover / mousemove, descubrí que puede hacerlo utilizando javascript nativo, como este:

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

Esto funcionará en la versión de escritorio y no hará nada en la versión móvil.

Y para un poco más de compatibilidad ...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});
Adauto
fuente
1
Ese bit "si el contenido de la página cambia en el evento mousemove, no se envían eventos posteriores en la secuencia" realmente lo hizo por mí. Tenía una página donde los enlaces de encabezado requerirían un doble toque donde los botones en el contenido (con todas las transiciones css3 felices en em) solo requerirían un solo toque. Apareció que los enlaces del encabezado tenían un pseudo-elemento que pasó de opacidad: 0 a opacidad: 1 al pasar el ratón. Al eliminar ese efecto, el problema se resolvió de inmediato y encontré una solución CSS para seguir obteniendo el aspecto que quería.
Fake Haak
3

La solución de cduruk fue bastante efectiva, pero causó problemas en algunas partes de mi sitio. Debido a que ya estaba usando jQuery para agregar la clase de desplazamiento de CSS, la solución más fácil era simplemente no agregar la clase de desplazamiento de CSS en dispositivos móviles (o más precisamente, agregarla SOLO cuando NO esté en un dispositivo móvil).

Aquí estaba la idea general:

var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);

if (!(ios)) {
    $(".portfolio-style").hover(
        function(){
            $(this).stop().animate({opacity: 1}, 100);
            $(this).addClass("portfolio-red-text");
        },
        function(){
            $(this).stop().animate({opacity: 0.85}, 100);
            $(this).removeClass("portfolio-red-text");
        }
    );
}

* código reducido con fines ilustrativos

woop
fuente
1
Esta es claramente la respuesta. Las otras "soluciones" no solucionan el problema. El safari de iOS es claramente erróneo al pensar que queremos pasar el cursor primero. Otros sistemas operativos tienen características reales de desplazamiento al pasar el mouse sobre un elemento.
Joshua Pack
Esto fue lo único que funcionó para mí. Muchas gracias!
tx291
2

Creo que sería prudente intentarlo mouseenteren lugar de mouseover. Es lo que se usa internamente cuando se vincula .hover(fn,fn)y generalmente es lo que desea.

Paul Irish
fuente
1

Tuve los siguientes problemas con las soluciones existentes y encontré algo que parece resolverlos a todos. Esto supone que estás apuntando a algo entre navegadores, dispositivos cruzados, y no quieres que el dispositivo lo detecte.

Los problemas que esto resuelve

Usando solo touchstarto touchend:

  • Hace que el evento se active cuando las personas intentan desplazarse más allá del contenido y simplemente pasan el dedo sobre este elemento cuando comienzan a deslizar, lo que desencadena la acción inesperadamente.
  • Puede provocar que el evento se active en Longpress , similar al clic derecho en el escritorio. Por ejemplo, si su evento de clic va a URL X, y el usuario presiona para abrir X en una nueva pestaña, el usuario se confundirá al encontrar X abierto en ambas pestañas. En algunos navegadores (por ejemplo, iPhone), incluso puede evitar que aparezca el menú de pulsación larga.

Desencadenar mouseovereventos en touchstarty mouseoutsobre touchmovetiene consecuencias menos graves, pero no interfiere con el comportamiento habitual del navegador, por ejemplo:

  • Una pulsación larga provocaría un mouseover que nunca termina.
  • Muchos navegadores de Android tratan la ubicación del dedo touchstartcomo un mouseover, que se mouseoutedita en el siguiente touchstart. Por lo tanto, una forma de ver el contenido del mouseover en Android es tocar el área de interés y mover el dedo, desplazando ligeramente la página. Tratando touchmovecomo mouseoutrompe esto.

La solución

En teoría, podría agregar una bandera con touchmove, pero los iPhones activan el movimiento táctil incluso si no hay movimiento. En teoría, usted podría comparar el touchstarte touchendcaso pageXy pageY aunque en iPhones, no hay touchend pageXopageY .

Desafortunadamente, para cubrir todas las bases, termina siendo un poco más complicado.

$el.on('touchstart', function(e){
    $el.data('tstartE', e);
    if(event.originalEvent.targetTouches){
        // store values, not reference, since touch obj will change
        var touch = e.originalEvent.targetTouches[0];
        $el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
    }
});
$el.on('touchmove', function(e){
    if(event.originalEvent.targetTouches){
        $el.data('tstartM', event.originalEvent.targetTouches[0]);
    }
});

$el.on('click touchend', function(e){
    var oldE = $el.data('tstartE');
    if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
        $el.data('tstartE',false);
        return;
    }
    if( $el.data('iosTouchM') && $el.data('tstartT') ){
        var start = $el.data('tstartT'), end = $el.data('tstartM');
        if( start.clientX != end.clientX || start.clientY != end.clientY ){
            $el.data('tstartT', false);
            $el.data('tstartM', false);
            $el.data('tstartE',false);
            return;
        }
    }
    $el.data('tstartE',false);

En teoría, hay formas de obtener el tiempo exacto utilizado para una pulsación larga en lugar de solo usar 1000 como aproximación, pero en la práctica no es tan simple y es mejor usar un proxy razonable .

user56reinstatemonica8
fuente
1

La respuesta de MacFreak fue extremadamente útil para mí. Aquí hay un código práctico en caso de que te ayude.

PROBLEMA : la aplicación de toque significa que cada vez que desliza el dedo sobre un elemento, responde como si lo hubiera presionado, incluso si solo intentara pasar.

Estoy creando un efecto con jQuery que desvanece una línea debajo de algunos botones para "resaltar" el botón suspendido. No quiero que esto signifique que tienes que presionar el botón dos veces en dispositivos táctiles para seguir el enlace.

Aquí están los botones:

<a class="menu_button" href="#">
    <div class="menu_underline"></div>
</a>

Quiero que el div "menu_underline" se desvanezca con el mouseover y se desvanezca con el mouseout. PERO quiero que los dispositivos táctiles puedan seguir el enlace con un solo clic, no dos.

SOLUCIÓN : Aquí está jQuery para que funcione:

//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
    $(this).find(".menu_underline").fadeIn();
});

//Mouse Out   
$('.menu_button').bind('mouseleave touchmove click', function(){
    $(this).find(".menu_underline").fadeOut();
});

Muchas gracias por su ayuda en este MacFreak.

Mad Dog Cadogen
fuente
1

Me acabo de enterar de que funciona si agregas un oyente vacío, no me preguntes por qué, pero lo probé en iPhone y iPad con iOS 9.3.2 y funcionó bien.

if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
    var elements = document.getElementsByTagName('a');
    for(var i = 0; i < elements.length; i++){
        elements[i].addEventListener('touchend',function(){});
    }
}
freek van der wand
fuente
0

Tuve el mismo problema pero no en un dispositivo táctil. El evento se dispara cada vez que haces clic. Hay algo sobre la cola de eventos más o menos.

Sin embargo, mi solución fue la siguiente: al hacer clic en el evento (¿o tocar?) Configura un temporizador. Si se vuelve a hacer clic en el enlace dentro de X ms, simplemente devuelve falso.

Para establecer el temporizador por elemento, puede usar $.data().

Esto también puede solucionar el problema @Ferdy descrito anteriormente.

Ionuț Staicu
fuente
¿Puedes publicar cómo se ve este código? Tengo este problema de que el evento de clic se active dos veces.
elegante
0

Si usa Modernizr, es muy fácil usar Modernizr.touch como se mencionó anteriormente.

Sin embargo, prefiero usar una combinación de Modernizr.touch y pruebas de agente de usuario, solo para estar seguro.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};

Si no usa Modernizr, simplemente puede reemplazar la Modernizr.touchfunción anterior con('ontouchstart' in document.documentElement)

También tenga en cuenta que probar el agente de usuario iemobile le dará una gama más amplia de dispositivos móviles de Microsoft detectados que Windows Phone.

Peter Pan
fuente
0

Puedes usar click touchend,

ejemplo:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

El ejemplo anterior afectará a todos los enlaces en dispositivos táctiles.

Si desea orientar solo enlaces específicos, puede hacerlo estableciendo una clase en ellos, es decir:

HTML:

<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>

Jquery:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Salud,

Jeroen

Jeroen W
fuente
0

Me encontré con una situación similar en la que tenía eventos vinculados a los estados del mouseenter / mouseleave / click de un elemento, pero en un iPhone, el usuario tenía que hacer doble clic en el elemento para activar primero el evento del mouseenter, y luego nuevamente para activar el evento click .

Resolví esto usando un método similar al anterior, pero hice uso del complemento jQuery $ .browser (para jQuery 1.9>) y agregué un evento .trigger al evento de enlace del mouseenter, de la siguiente manera:

// mouseenter event
$('.element').on( "mouseenter", function() {
    // insert mouseenter events below

    // double click fix for iOS and mouseenter events
    if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
});
// mouseleave event
$('.element').on( "mouseleave", function() { 
    // insert mouseout events below
});
// onclick event
$('.element').on( "click", function() {
    // insert click events below
});

El .trigger evita la necesidad de hacer doble clic en el elemento activando el controlador de eventos .click en el mouseenter (o clic inicial) del elemento cuando se ve en iPhones o iPads. Puede que no sea la solución más elegante, pero funciona muy bien en mi caso y utiliza un complemento que ya tenía instalado, y requería que agregara una sola línea de código para que mis eventos existentes funcionen bajo estos dispositivos.

Puede obtener el complemento jQuery $ .browser aquí: https://github.com/gabceb/jquery-browser-plugin

tabla de espiritismo
fuente
0

Solo una mejora para evitar la redirección cuando desliza su dedo en un enlace por error.

// tablet "one touch (click)" X "hover" > link redirection
$('a').on('touchmove touchend', function(e) {

    // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
    if (e.type == 'touchmove') {
        $.data(this, "touchmove_cancel_redirection", true );
        return;
    }

    // if it's a simple touchend, data() for this element doesn't exist.
    if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    }

    // if touchmove>touchend, to be redirected on a future simple touchend for this element
    $.data(this, "touchmove_cancel_redirection", false );
});
Lenor
fuente
0

Con la inspiración de MacFreak, armé algo que funciona para mí.

Este método js evita que el desplazamiento se pegue en un ipad y evita que el clic se registre como dos clics en algunos casos. En CSS, si tiene alguna clase: hover psudo en su CSS, cámbiela a .hover Por ejemplo .some-class: hover a .some-class.hover

Pruebe este código en un ipad para ver cómo los métodos css y js hover se comportan de manera diferente (solo en efecto de desplazamiento). El botón CSS no tiene una alerta de clic elegante. http://jsfiddle.net/bensontrent/ctgr6stm/

function clicker(id, doStuff) {
  id.on('touchstart', function(e) {
    id.addClass('hover');
  }).on('touchmove', function(e) {
    id.removeClass('hover');
  }).mouseenter(function(e) {
    id.addClass('hover');
  }).mouseleave(function(e) {
    id.removeClass('hover');
  }).click(function(e) {
    id.removeClass('hover');
    //It's clicked. Do Something
    doStuff(id);
  });
}

function doStuff(id) {
  //Do Stuff
  $('#clicked-alert').fadeIn(function() {
    $(this).fadeOut();
  });
}
clicker($('#unique-id'), doStuff);
button {
  display: block;
  margin: 20px;
  padding: 10px;
  -webkit-appearance: none;
  touch-action: manipulation;
}
.hover {
  background: yellow;
}
.btn:active {
  background: red;
}
.cssonly:hover {
  background: yellow;
}
.cssonly:active {
  background: red;
}
#clicked-alert {
  display: none;
}
<button id="unique-id" class="btn">JS Hover for Mobile devices<span id="clicked-alert"> Clicked</span>

</button>
<button class="cssonly">CSS Only Button</button>
<br>This js method prevents hover from sticking on an ipad, and prevents the click registering as two clicks. In CSS, if you have any :hover in your css, change them to .hover For example .some-class:hover to .some-class.hover

Benson
fuente
0

Para que los enlaces funcionen sin romper el desplazamiento táctil, resolví esto con el evento "tap" de jQuery Mobile:

    $('a').not('nav.navbar a').on("tap", function () {
        var link = $(this).attr('href');
        if (typeof link !== 'undefined') {
            window.location = link;
        }
    });
mooses
fuente
0

Llego demasiado tarde, lo sé, pero esta es una de las soluciones más fáciles que he encontrado:

    $('body').on('touchstart','*',function(){   //listen to touch
        var jQueryElement=$(this);  
        var element = jQueryElement.get(0); // find tapped HTML element
        if(!element.click){
            var eventObj = document.createEvent('MouseEvents');
            eventObj.initEvent('click',true,true);
            element.dispatchEvent(eventObj);
        }
    });

Esto no solo funciona para enlaces (etiquetas de anclaje) sino también para otros elementos. Espero que esto ayude.

writeToBhuwan
fuente
0

Este fragmento corto parece funcionar. Activa el evento de clic cuando se toca el enlace:

  $('a').on('touchstart', function() {
    $(this).trigger('click');
  });
Flo Develop
fuente
0

Ninguno de la otra respuesta funciona para mí. Mi aplicación tiene muchos oyentes de eventos, casillas de verificación propias y enlaces que tienen oyentes y enlaces sin oyentes.

Yo uso esto:

var selector = "label, a, button";
var timer;
var startX;
var startY;
$(document).on("click", selector, function (e) {
    if ($(this).data("touched") === true) {
        e.stopImmediatePropagation();
        return false;
    }
    return;
}).on("touchend", selector, function (e) {
    if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
        // user action is not a tap
        return;
    var $this = $(this);
    // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
    this.click();
    // prevents double click
    $this.data("touched", true);
    if (timer)
        clearTimeout(timer);
    setTimeout(function () {
        $this.data("touched", false);
    }, 400);
    e.stopImmediatePropagation();
    return false;
}).on("touchstart", function (e) {
    startX = e.originalEvent.changedTouches[0].screenX;
    startY = e.originalEvent.changedTouches[0].screenY;
});
Magu
fuente
0

Esto funciona para mí cuando tienes jquery ui desplegable

if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
      $('.ui-autocomplete').off('menufocus hover mouseover');
}
Makubex
fuente
0

Evite cambiar el estilo de "visualización" dentro del evento hover css. Tenía "display: block" en estado de desplazamiento. Después de eliminar ios se fue a lins con un solo toque. Por cierto, parece que las últimas actualizaciones de iOS arreglaron esta "característica"

Hellbyte
fuente
0

La forma más simple de resolver hacer doble clic en el iPad es envolver su CSS para el efecto de desplazamiento en la consulta de medios @media (pointer: fine):

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

El CSS que se incluye en esta consulta de medios se aplicará solo en el escritorio.

La explicación de esta solución está aquí https://css-tricks.com/annoying-mobile-double-tap-link-issue/

Galina
fuente
-1

Podrías comprobar navigator.userAgentasí:

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}

pero tendrías que buscar moras, droides y otros dispositivos con pantalla táctil. También puede enlazar los mouseovers solo si el userAgent contiene Mozilla, IE, Webkit u Opera, pero aún necesita buscar algunos dispositivos porque el Droid, por ejemplo, informa su cadena de userAgent como:

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

La cadena del iPhone es similar. Si solo realiza la pantalla para iPhone, iPod, iPad, Android y Blackberry, es posible que obtenga la mayoría de las computadoras de mano, pero no todas.

jasongetsdown
fuente
Creo que, por ahora, para no volverse loco, lo mejor que podría hacer es simplemente un guión que omita los eventos de desplazamiento ... así que supongo que la primera respuesta fue buena ... y sí, tiene razón ... debería piense en todos los otros dispositivos ... ¡ojalá Jquery o algún complemento tuvieran este tipo de función de descción ...!
Francesco
wurfl.sourceforge.net Esta podría ser su respuesta. Es una base de datos de dispositivos inalámbricos. No será tan sencillo como lo sería un complemento jQuery, ¡pero siempre puedes escribir uno! También hay tera-wurfl.com que usa un databse en lugar de un archivo xml. No he investigado mucho, pero es posible que haya una versión alojada para que no tenga que preocuparse por mantener actualizado su archivo wurfl o su base de datos tera-wurfl.
jasongetsdown
1
¿Me estoy perdiendo algo o la pregunta NO era sobre la detección de iPads, sino sobre cómo solucionar un comportamiento específico en iPads?
Andrew Hedges
55
UA husmeando? How 90's: P
Macha
-1

Simplemente haga una consulta de medios CSS que excluya tabletas y dispositivos móviles y coloque el cursor allí. Realmente no necesitas jQuery o JavaScript para esto.

@media screen and (min-device-width:1024px) {
    your-element:hover {
        /* Do whatever here */
    }
}

Y asegúrese de agregar esto a su cabeza html para asegurarse de que se calcule con los píxeles reales y no con la resolución.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
Dalibor
fuente