Como posso reconhecer eventos de toque usando o jQuery no Safari para iPad? É possível?

191

É possível reconhecer eventos de toque no navegador Safari do iPad usando o jQuery?

Eu usei eventos mouseOver e mouseOut em um aplicativo da web. Existem eventos semelhantes para o navegador Safari do iPad, pois não existem eventos como mouseOut e mouseMove?

Abhishek B.
fonte

Respostas:

240

O jQuery principal não tem nada de especial para eventos de toque, mas você pode facilmente criar seu próprio usando os seguintes eventos

  • touchstart
  • touchmove
  • toque
  • touchcancel

Por exemplo, o touchmove

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
    var touch = e.touches[0];
    alert(touch.pageX + " - " + touch.pageY);
}, false);

Isso funciona na maioria dos navegadores baseados no WebKit (incluindo Android).

Aqui está uma boa documentação .

David Pean
fonte
2
Muito obrigado David, acho que vai funcionar, mas o que é e.touches [0]? você pode descrever o argumento "e" em detalhes?
Abhishek B. 21/01
7
e é o objeto de evento que é passado automaticamente para o manipulador. Para o navegador safari (e também para o Android), ele agora contém uma variedade de todos os toques que o usuário fez na tela. Cada toque tem suas próprias propriedades (x, y, por exemplo)
David Pean
1
Agora, como você vai encontrar o elemento para evento de disparo em -__-
Muhammad Umer
148

Se você estiver usando o jQuery 1.7+, é ainda mais simples do que todas essas outras respostas.

$('#whatever').on({ 'touchstart' : function(){ /* do something... */ } });
Timothy Perez
fonte
1
Sim, Timothy, eu não estava usando a versão 1.7+ no momento em que iniciei o meu projeto. agora onwords eu estou usando jquery 1.7+ .. Obrigado pela boa sugestão e resposta .. Muito obrigado. :)
Abhishek B.
7
Isso funciona bem. Eu precisava clicar e iniciar o touch para fazer a mesma coisa e estou acostumado com a sintaxe que não é objeto, como$('#whatever').on('touchstart click', function(){ /* do something... */ });
goodeye
1
quando eu vou $('#whatever').on({ 'touchstart' : function(ev){}});, evparece não ter nenhuma informação sobre os toques (toques, toques de destino ou toques alterados)
Octopus
8
@ Octopus: Você encontrará as informações sobre toques em ev.originalEvent.
Peter Bloomfield
1
@edonbajrami sim, é claro. verifique os documentos e procure por "eventos delegados". $ ("# elemento para monitorar novos elementos"). on ("eventX", "#element", function (evento) {/ * qualquer que seja * /});
honk31
24

A abordagem mais simples é usar uma biblioteca JavaScript multitoque como o Hammer.js . Então você pode escrever um código como:

canvas
    .hammer({prevent_default: true})
    .bind('doubletap', function(e) { // And double click
        // Zoom-in
    })
    .bind('dragstart', function(e) { // And mousedown
        // Get ready to drag
    })
    .bind('drag', function(e) { // And mousemove when mousedown
        // Pan the image
    })
    .bind('dragend', function(e) { // And mouseup
        // Finish the drag
    });

E você pode continuar. Ele suporta toque, toque duplo, deslize, segure, transforme (ou seja, belisque) e arraste. Os eventos de toque também são acionados quando ações equivalentes do mouse acontecem, para que você não precise gravar dois conjuntos de manipuladores de eventos. Ah, e você precisa do plugin jQuery se quiser escrever da maneira jQueryish como eu fiz.

David Johnstone
fonte
29
a solução "mais simples" nunca envolve tornar um problema mais complicado adicionando bibliotecas
Octopus
13
@ Octopus A solução mais simples é usar o hammer.js que abstrai as dores de cabeça entre navegadores. Use a extensão jQuery para estar na sua zona familiar. Não me parece muito complicado.
trusktr
1
a suposta solução "mais simples" geralmente é aquela que as pessoas mais estragam ... o que quer que você faça, não se esqueça de garantir que sua solução funcione em dispositivos que suportam toque e mouse, como o Microsoft Surface
Simon_Weaver
1
@Octopus: "Quando tudo que você tem é um martelo [sic] ... tudo parece um prego" :)
Ido Codificação
É HAMMER TIME! Obrigado por compartilhar esta biblioteca, foi fácil de instalar no meu aplicativo e começar a funcionar! Demorou um segundo para configurar porque o manipulador de eventos é diferente, mas um console.log (evento) simples informa o que você precisa. OBRIGADO!
419 Andy
24

Usar o touchstart ou touchend sozinho não é uma boa solução, porque se você rolar a página, o dispositivo a detectará como toque ou toque também. Portanto, a melhor maneira de detectar um evento de toque e clique ao mesmo tempo é apenas detectar os eventos de toque que não estão movendo a tela (rolagem). Para fazer isso, basta adicionar este código ao seu aplicativo:

$(document).on('touchstart', function() {
    detectTap = true; // Detects all touch events
});
$(document).on('touchmove', function() {
    detectTap = false; // Excludes the scroll events from touch events
});
$(document).on('click touchend', function(event) {
    if (event.type == "click") detectTap = true; // Detects click events
       if (detectTap){
          // Here you can write the function or codes you want to execute on tap

       }
 });

Eu testei e funciona bem para mim no iPad e iPhone. Ele detecta o toque e pode distinguir o toque e o toque de rolagem facilmente.

Iman Sedighi
fonte
2
Esta solução parece ser a mais simples que encontrei e parece funcionar muito bem no iOS.
Joshua Lawrence Austill 22/03
Eu usei o jquery mobile primeiro, mas depois interferiu com outras funcionalidades. Estou usando isso agora e funciona perfeitamente. Sem problemas até agora.
Anurag Priyadarshi
18

Você pode usar .on () para capturar vários eventos e testar o toque na tela, por exemplo:

$('#selector')
.on('touchstart mousedown', function(e){
  e.preventDefault();
  var touch = e.touches[0];
  if(touch){
    // Do some stuff
  }
  else {
    // Do some other stuff
  }
});
pena
fonte
exceto que .bindestá obsoleto. Você deve usar.on
jcuenod
15

O jQuery Core não tem nada de especial, mas você pode ler na página Eventos do jQuery Mobile sobre diferentes eventos de toque, que também funcionam em outros dispositivos que não sejam iOS.

Eles são:

  • toque
  • taphold
  • furto
  • deslize para a esquerda
  • desliza para a direita

Observe também que, durante eventos de rolagem (com base no toque em dispositivos móveis), os dispositivos iOS congelam a manipulação do DOM durante a rolagem.

Karol
fonte
Obrigado por dar o seu tempo importante para a minha pergunta. Estou olhando para os eventos do Jquery Mobile. Obrigado.
Abhishek B.
Esses eventos não são verdadeiramente representativos da interação real com o toque.
trusktr
O jQuery Core é um substantivo próprio real?
Peter Mortensen
6

Eu estava um pouco preocupado em usar apenas o touchmove no meu projeto, pois ele parece disparar apenas quando o seu toque se move de um local para outro (e não no toque inicial). Então eu combinei com o touchstart , e isso parece funcionar muito bem no toque inicial e em qualquer movimento.

<script>

function doTouch(e) {
    e.preventDefault();
    var touch = e.touches[0];

    document.getElementById("xtext").innerHTML = touch.pageX;
    document.getElementById("ytext").innerHTML = touch.pageY;   
}

document.addEventListener('touchstart', function(e) {doTouch(e);}, false);
document.addEventListener('touchmove', function(e) {doTouch(e);}, false);

</script>

X: <div id="xtext">0</div>
Y: <div id="ytext">0</div>
hanamj
fonte
Eu também adicionei este para detectar quanto tempo se passou desde o último evento ..document.getElementById("ttime").innerHTML = ((new Date()) - touchTime); touchTime = new Date();
hanamj
3

Acabei de testar o plug-in GitHub jQuery Touch Events da benmajor para as versões 1.4 e 1.7+ do jQuery. É leve e funciona perfeitamente com ambos one bindao mesmo tempo fornece suporte para um conjunto exaustivo de eventos de toque.

Rohan
fonte