Eu escrevi um plug-in jQuery para uso em computadores e dispositivos móveis. Gostaria de saber se existe uma maneira com JavaScript para detectar se o dispositivo tem capacidade de tela de toque. Estou usando o jquery-mobile.js para detectar os eventos da tela de toque e funciona no iOS, Android etc., mas também gostaria de escrever instruções condicionais com base no fato de o dispositivo do usuário ter uma tela de toque.
Isso é possível?
javascript
jquery
touch
screenm0nkey
fonte
fonte
Respostas:
Atualização: Leia a resposta do blmstr abaixo antes de colocar uma biblioteca de detecção de recursos inteira em seu projeto. Detectar o suporte ao toque real é mais complexo, e o Modernizr cobre apenas um caso de uso básico.
O Modernizr é uma maneira excelente e leve de realizar todos os tipos de detecção de recursos em qualquer site.
Ele simplesmente adiciona classes ao elemento html para cada recurso.
Você pode segmentar esses recursos facilmente em CSS e JS. Por exemplo:
E Javascript (exemplo jQuery):
fonte
Modernizr.touch
retornar inesperadamenteundefined
, você pode ter um Modernizr personalizado (você pode escolher) sem suporte para a detecção de eventos por toque.Você já tentou usar esta função? (É o mesmo que o Modernizr costumava usar.)
ATUALIZAÇÃO 1
document.createEvent("TouchEvent")
começaram a retornartrue
no cromo mais recente (v. 17). Modernizr atualizou isso há um tempo atrás. Confira o teste Modernizr aqui .Atualize sua função assim para fazê-la funcionar:
ATUALIZAÇÃO 2
Eu descobri que o acima não estava funcionando no IE10 (retornando false no MS Surface). Aqui está a correção:
ATUALIZAÇÃO 3
'onmsgesturechange' in window
retornará true em algumas versões de desktop do IE, portanto isso não é confiável. Isso funciona de maneira um pouco mais confiável:ATUALIZAÇÃO 2018
O tempo passa e existem novas e melhores maneiras de testar isso. Basicamente, extraí e simplifiquei a maneira como o Modernizr verificou:
Aqui eles estão usando o
touch-enabled
recurso de consulta de mídia não padrão , que eu acho meio estranho e uma prática ruim. Mas ei, no mundo real, acho que funciona. No futuro (quando suportados por todos), esses recursos de consulta de mídia poderão fornecer os mesmos resultados:pointer
ehover
.Confira a fonte de como o Modernizr está fazendo isso .
Para um bom artigo que explica os problemas com a detecção por toque, consulte: Stu Cox: você não pode detectar uma tela sensível ao toque .
fonte
true
oufalse
. Você pode ler mais sobre isso aqui: stackoverflow.com/questions/4686583/…in
operador já avalia como um booleano.'onmsgesturechange'
está avaliando a verdade mesmo em dispositivos sem toque (PC).window.navigator.msMaxTouchPoints
parece ser mais preciso. Encontrei aqui .Como o Modernizr não detecta o IE10 no Windows Phone 8 / WinRT, uma solução simples para vários navegadores é:
Você só precisa verificar uma vez, pois o dispositivo não oferece suporte repentino ou não ao toque; basta armazená-lo em uma variável para poder usá-lo várias vezes com mais eficiência.
fonte
return !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);
(para combinar as duas respostas) Também funciona bem no IE10!'onmsgesturechange' in window
retorna true no desktop IE10 mesmo quando o toque é possívelfunction isTouchDevice() { return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);}
Usando todos os comentários acima, montei o seguinte código que funciona para minhas necessidades:
Eu testei isso no iPad, Android (navegador e Chrome), Blackberry Playbook, iPhone 4s, Windows Phone 8, IE 10, IE 8, IE 10 (Windows 8 com tela sensível ao toque), Opera, Chrome e Firefox.
Atualmente, ele falha no Windows Phone 7 e ainda não consegui encontrar uma solução para esse navegador.
Espero que alguém ache isso útil.
fonte
true
no meu Firefox 32 no windows 7 :(Desde a introdução dos recursos de mídia de interação, você simplesmente pode:
https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer
Atualização (devido aos comentários): A solução acima é detectar se um "ponteiro aproximado" - geralmente uma tela sensível ao toque - é o principal dispositivo de entrada. Caso deseje detectar se um dispositivo com, por exemplo, um mouse também possui uma tela sensível ao toque, você pode usar
any-pointer: coarse
.Para obter mais informações, dê uma olhada aqui: Detectando que o navegador não possui mouse e é apenas de toque
fonte
(pointer: coarse)
como você provavelmente está direcionando apenas a entrada principal. Pode ser usado na produção, pois os poucos navegadores não compatíveis são apenas para desktop. Há um ótimo artigo sobre isso em CSS-Tricks .Eu gosto deste:
fonte
function isTouchDevice(){ return (window.ontouchstart !== undefined); }
var isTouch = 'ontouchstart' in window;
no entanto, isso não funciona com o Chrome mais recente (v31),var isTouch = 'createTouch' in window.document;
ainda está funcionando.touchstart
falharão ao reconhecer o Surface como um dispositivo de toque porque o IE usapointer
eventos.Se você usa o Modernizr , é muito fácil usar
Modernizr.touch
como mencionado anteriormente.No entanto, prefiro usar uma combinação de
Modernizr.touch
e teste de agente de usuário, apenas por segurança.Se você não usa o Modernizr, pode simplesmente substituir a
Modernizr.touch
função acima por('ontouchstart' in document.documentElement)
Observe também que ao testar o agente do usuário,
iemobile
você terá uma gama mais ampla de dispositivos móveis Microsoft detectados do queWindows Phone
.Veja também esta pergunta do SO
fonte
/(iphone|ipod|ipad|android|iemobile|blackberry|bada)/.test(window.navigator.userAgent.toLowerCase())
Tentamos a implementação modernizr, mas a detecção dos eventos de toque não é mais consistente (o IE 10 possui eventos de toque na área de trabalho do Windows, o IE 11 funciona, porque eles eliminaram os eventos de toque e adicionaram a API do ponteiro).
Decidimos otimizar o site como um site de toque, desde que não saibamos que tipo de entrada o usuário possui. Isso é mais confiável do que qualquer outra solução.
Nossas pesquisas dizem que a maioria dos usuários de desktop se move com o mouse sobre a tela antes de clicar, para que possamos detectá-los e alterar o comportamento antes que eles possam clicar ou passar o mouse sobre qualquer coisa.
Esta é uma versão simplificada do nosso código:
fonte
Violino de trabalho
Eu consegui assim;
fonte
Há algo melhor do que verificar se eles têm uma tela sensível ao toque, é verificar se eles estão usando, além disso, é mais fácil verificar.
fonte
Este funciona bem mesmo em tablets Windows Surface !!!
fonte
Usei partes do código acima para detectar se o toque era exibido, para que meus iframes do fancybox aparecessem em computadores desktop e não no toque. Notei que o Opera Mini para Android 4.0 ainda estava sendo registrado como um dispositivo sem toque ao usar o código do blmstr sozinho. (Alguem sabe por quê?)
Acabei usando:
fonte
/iPhone|iPod|iPad|Android|BlackBerry/
?O maior problema na tentativa de detectar o toque está nos dispositivos híbridos que suportam o toque e o trackpad / mouse. Mesmo se você conseguir detectar corretamente se o dispositivo do usuário oferece suporte ao toque, o que você realmente precisa fazer é detectar qual dispositivo de entrada o usuário está usando no momento . Há uma descrição detalhada desse desafio e uma possível solução aqui .
Basicamente, a abordagem para descobrir se um usuário acabou de tocar na tela ou se usou um mouse / trackpad é registrar os eventos a
touchstart
emouseover
na página:Uma ação de toque acionará esses dois eventos, embora o primeiro (
touchstart
) sempre seja o primeiro na maioria dos dispositivos. Portanto, contando com essa sequência previsível de eventos, é possível criar um mecanismo que inclua ou remova dinamicamente umacan-touch
classe na raiz do documento para refletir o tipo de entrada atual do usuário neste momento no documento:Mais detalhes aqui .
fonte
Confira esta postagem , ele fornece um snippet de código muito bom sobre o que fazer quando dispositivos touch são detectados ou o que fazer se o evento touchstart for chamado:
fonte
Eu evitaria usar a largura da tela para determinar se um dispositivo é um dispositivo de toque. Existem telas sensíveis ao toque muito maiores que 699px, pense no Windows 8. Navigatior.userAgent pode ser bom substituir mensagens falsas.
Eu recomendaria verificar esta questão no Modernizr.
Você deseja testar se o dispositivo suporta eventos de toque ou é um dispositivo de toque. Infelizmente, isso não é a mesma coisa.
fonte
Não, não é possível. As excelentes respostas dadas são sempre parciais, porque qualquer método determinado produzirá falsos positivos e falsos negativos. Mesmo o navegador nem sempre sabe se uma tela sensível ao toque está presente, devido às APIs do SO, e o fato pode mudar durante uma sessão do navegador, principalmente com disposições do tipo KVM.
Veja mais detalhes neste excelente artigo:
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
O artigo sugere que você reconsidere as suposições que fazem você querer detectar telas sensíveis ao toque; elas provavelmente estão erradas. (Eu verifiquei o meu próprio aplicativo e minhas suposições estavam realmente erradas!)
O artigo conclui:
fonte
Muitos desses trabalhos, mas requerem jQuery ou linters javascript, reclamam da sintaxe. Considerando que sua pergunta inicial pede uma maneira "JavaScript" (não jQuery, não Modernizr) de resolver isso, aqui está uma função simples que funciona sempre. Também é o mínimo possível.
Um último benefício que mencionarei é que esse código é independente da estrutura e do dispositivo. Aproveitar!
fonte
function isTouchScreen() { return window.matchMedia('(hover: none)').matches;}
Isso funcionou para mim, por isso estou adicionando uma contribuição a essa resposta, pois também esperava um encadeamento de baunilha JS quando o Google me trouxe aqui.Parece que o Chrome 24 agora suporta eventos de toque, provavelmente para Windows 8. Portanto, o código postado aqui não funciona mais. Em vez de tentar detectar se o toque é suportado pelo navegador, agora estou vinculando os eventos de toque e clique e certificando-me de que apenas um seja chamado:
E então chamando:
Espero que isto ajude !
fonte
Todos os navegadores suportados, exceto o Firefox para desktop, sempre TRUE por causa do design responsivo do Firefox para desktop, mesmo que você clique no botão sensível ao toque ou não!
Espero que a Mozilla conserte isso na próxima versão.
Estou usando o Firefox 28 desktop.
fonte
true
:(jQuery v1.11.3
Há muitas informações boas nas respostas fornecidas. Recentemente, porém, passei muito tempo tentando vincular tudo a uma solução de trabalho para realizar duas coisas:
Além deste post e Detectando dispositivos de tela de toque com Javascript , achei este post de Patrick Lauke extremamente útil: https://hacks.mozilla.org/2013/04//detecting-touch-its-the-why-not-the-how /
Aqui está o código ...
Importante! o
*.on( events [, selector ] [, data ], handler )
método precisa ter um seletor, geralmente um elemento, que possa manipular o evento "touchstart" ou qualquer outro evento semelhante associado a toques. Nesse caso, é o elemento de hiperlink "a".Agora, você não precisa manipular o clique normal do mouse em JavaScript, porque você pode usar CSS para manipular esses eventos usando seletores para o elemento "a" do hiperlink, assim:
Nota: Existem outros seletores também ...
fonte
ou
seria uma verificação mais completa, suponho.
fonte
ua
se referenavigator.userAgent
. Além disso, a detecção pela largura da tela pode dar um resultado falso se alguém abrir um navegador no modo não em tela cheia.Eu uso:
no jQuery mobile 1.0.1
fonte
Também lutei bastante com diferentes opções sobre como detectar em Javascript se a página é exibida em um dispositivo com tela de toque ou não. A IMO, a partir de agora, não existe uma opção real para detectar a opção corretamente. Os navegadores relatam eventos de toque em máquinas de desktop (porque o sistema operacional talvez esteja pronto para toque) ou algumas soluções não funcionam em todos os dispositivos móveis.
No final, percebi que estava seguindo a abordagem errada desde o início: se minha página fosse semelhante em dispositivos de toque e sem toque, talvez eu não devesse me preocupar em detectar a propriedade: meu cenário era desativar dicas de ferramentas sobre botões em dispositivos de toque, pois levam a toques duplos nos quais eu queria um único toque para ativar o botão.
Minha solução foi refatorar a visualização para que nenhuma dica de ferramenta fosse necessária sobre um botão e, no final, não precisei detectar o dispositivo de toque do Javascript com métodos que todos têm suas desvantagens .
fonte
Você pode instalar o modernizador e usar um evento de toque simples. Isso é muito eficaz e funciona em todos os dispositivos que eu testei, inclusive na superfície do Windows!
Eu criei um jsFiddle
fonte
A resposta prática parece ser aquela que considera o contexto:
1) Site público (sem login)
Codifique a interface do usuário para trabalhar com as duas opções juntas.
2) Site de logon
Capture se um movimento do mouse ocorreu no formulário de logon e salve-o em uma entrada oculta. O valor é passado com as credenciais de login e adicionado à sessão do usuário , para que possa ser usado durante toda a duração da sessão.
Jquery para adicionar apenas à página de login:
(+1 para @Dave Burt e +1 para @Martin Lantzsch em suas respostas)
fonte
O problema
Devido a dispositivos híbridos que usam uma combinação de toque e entrada de mouse, você precisa poder alterar dinamicamente o estado / variável que controla se um trecho de código deve ser executado se o usuário é um usuário de toque ou não.
Os dispositivos de toque também são acionados
mousemove
na torneira.Solução
touchstart
evento seja disparado e defina-o como verdadeiro.Testado no Safari iOS e Chrome para Android.
Nota: não tem 100% de certeza nos eventos do ponteiro para o MS Surface, etc.
Codepen demo
fonte
Na verdade, pesquisei essa questão e considero todas as situações. porque também é um grande problema no meu projeto. Então, chego à função abaixo, que funciona para todas as versões de todos os navegadores em todos os dispositivos:
Dica : Definitivamente, o
isTouchDevice
just retornaboolean
valores.fonte
support
Objeto jQuery de extensão :E agora você pode verificá-lo em qualquer lugar, assim:
fonte
Isso parece estar funcionando bem para mim até agora:
fonte
Quando um mouse é conectado, pode-se supor com uma taxa de bits razoavelmente alta (eu diria praticamente 100%) que o usuário move o mouse pelo menos uma pequena distância após a página estar pronta - sem nenhum clique. O mecanismo abaixo detecta isso. Se detectado, considero isso um sinal de falta de suporte por toque ou, se suportado, de menor importância quando um mouse está em uso. O dispositivo de toque é assumido se não for detectado.
EDITAR Essa abordagem pode não atender a todos os propósitos. Ele pode ser usado para controlar a funcionalidade ativada com base na interação do usuário na página carregada, por exemplo, um visualizador de imagens. O código abaixo também deixará o evento mousemove vinculado a dispositivos sem mouse, como ele se destaca agora. Outras abordagens podem ser melhores.
Aproximadamente, é assim (desculpe pelo jQuery, mas semelhante em Javascript puro):
fonte