12k
All articles

Detecção de Dispositivos Touch com JavaScript

Detecte dispositivos touch em JavaScript com maxTouchPoints, Pointer Events e media queries CSS para híbridos e o tipo de entrada atual.

OpenReplay Team
OpenReplay Team
Detecção de Dispositivos Touch com JavaScript

A detecção de toque parece simples até você se deparar com um Surface Pro, um iPad com Magic Keyboard ou um Chromebook com tela sensível ao toque. Esses dispositivos híbridos quebram a suposição de que “toque” e “mouse” são mutuamente exclusivos—e é exatamente aí que a maioria das abordagens de detecção falha.

Este artigo vai direto ao ponto: o que realmente funciona, o que não funciona e quando você não deveria se preocupar em detectar toque.

Principais Conclusões

  • 'ontouchstart' in window não é confiável porque os navegadores o expõem de forma inconsistente, mesmo em dispositivos sem tela sensível ao toque.
  • navigator.maxTouchPoints > 0 é a verificação JavaScript simples mais confiável para capacidade de toque reportada em navegadores modernos.
  • Media queries CSS de ponteiro (pointer, any-pointer, hover) lidam com a maioria das adaptações de UI sem necessidade de JavaScript.
  • A API Pointer Events e sua propriedade pointerType permitem detectar o método de entrada atual do usuário, o que é muito mais útil em dispositivos híbridos do que uma verificação única no carregamento da página.

Por Que 'ontouchstart' in window Não É Suficiente

Por anos, desenvolvedores verificavam 'ontouchstart' in window como uma forma rápida de detectar capacidade de toque. O problema é que os navegadores expõem essa propriedade de forma inconsistente. Alguns navegadores desktop no Windows 8+ reportam como true mesmo sem uma tela sensível ao toque. O Chrome alternou seu comportamento ao longo das versões. É um sinal impreciso.

Confiar apenas em ontouchstart significa que você está detectando o comportamento do navegador, não a capacidade real do hardware.

A propriedade JavaScript mais confiável para detectar suporte a toque atualmente é navigator.maxTouchPoints. Ela retorna o número máximo de pontos de contato de toque simultâneos que o dispositivo suporta. Um valor maior que zero significa que o hardware reporta capacidade de toque.

function hasTouchSupport() {
  return navigator.maxTouchPoints > 0
}

Isso faz parte da especificação Pointer Events e é suportado em todos os navegadores modernos—Chrome, Firefox, Safari e Edge. É limpo, legível e não depende de detecção de manipuladores de eventos.

Nota: navigator.msMaxTouchPoints era o equivalente da era do IE. Você não precisa dele a menos que esteja mantendo código legado.

Quando Media Queries CSS de Ponteiro São a Ferramenta Melhor

Para a maioria das adaptações de UI, você não precisa de JavaScript. Media queries CSS de ponteiro permitem ajustar o estilo com base na precisão do dispositivo de entrada primário.

/* Segmenta dispositivos onde o ponteiro primário é grosseiro (ex: dedo) */
@media (pointer: coarse) {
  .btn {
    min-height: 48px;
  }
}

/* Segmenta qualquer ponteiro disponível que seja grosseiro, incluindo entradas secundárias */
@media (any-pointer: coarse) {
  .tooltip {
    display: none;
  }
}

/* Segmenta dispositivos onde hover não está disponível de forma confiável */
@media (hover: none) {
  .dropdown:hover .menu {
    display: none;
  }
}

A diferença entre pointer e any-pointer importa em dispositivos híbridos. pointer: coarse reflete apenas a entrada primária. any-pointer: coarse retorna verdadeiro se qualquer entrada conectada for grosseira—útil quando um dispositivo tem tanto mouse quanto tela sensível ao toque.

Pointer Events vs. Touch Events

Pointer Events são o modelo moderno e unificado para lidar com entrada de mouse, toque e caneta em JavaScript. Em vez de manter manipuladores separados de touchstart e mousedown, você escreve um:

element.addEventListener('pointerdown', (e) => {
  if (e.pointerType === 'touch') {
    // Lidar com entrada por toque
  } else if (e.pointerType === 'mouse') {
    // Lidar com entrada por mouse
  }
})

A propriedade pointerType informa exatamente o que o usuário está fazendo neste momento—não o que seu dispositivo é teoricamente capaz de fazer. Essa é a distinção que mais importa em dispositivos híbridos.

Touch Events legados (touchstart, touchmove, touchend) ainda são suportados na maioria dos navegadores, mas não estão disponíveis em todos os ambientes e não cobrem entrada de mouse ou caneta. Prefira Pointer Events para código novo.

O Problema dos Dispositivos Híbridos

Um usuário em um laptop com toque pode iniciar uma sessão com mouse e depois tocar na tela. Qualquer detecção que você faça no carregamento da página já está desatualizada.

Em vez de fixar um único resultado de detecção, escute eventos pointerdown e leia e.pointerType dinamicamente. Isso permite adaptar a UI com base no que o usuário está realmente fazendo, não no que seu dispositivo suporta em teoria.

O Que Usar e Quando

ObjetivoAbordagem Recomendada
Ajustar tamanhos de botões ou áreas de toqueCSS @media (pointer: coarse)
Suprimir UI exclusiva de hoverCSS @media (hover: none)
Verificar capacidade de hardware touch em JSnavigator.maxTouchPoints > 0
Lidar com eventos de entrada em todos os tiposAPI Pointer Events
Detectar tipo de entrada atual dinamicamenteevent.pointerType em pointerdown

Conclusão

Evite completamente a detecção por user agent. Para ajustes de UI, media queries CSS de ponteiro lidam com a maioria dos casos sem uma única linha de JavaScript. Quando você precisar de JavaScript, navigator.maxTouchPoints fornece um sinal de hardware confiável, e a API Pointer Events fornece contexto de entrada em tempo real. Juntos, eles cobrem toda a gama de dispositivos modernos—incluindo os híbridos que tornam a detecção simples não confiável.

Perguntas Frequentes

É seguro usar navigator.maxTouchPoints em todos os navegadores modernos?

Sim. navigator.maxTouchPoints faz parte da especificação Pointer Events e é suportado no Chrome, Firefox, Safari e Edge. Geralmente retorna zero em dispositivos que não reportam suporte a toque, e um número inteiro positivo em dispositivos com capacidade de toque. É a verificação de propriedade única mais confiável disponível em JavaScript hoje para detectar suporte a toque.

Por que não devo usar detecção de user agent para detectar dispositivos touch?

Strings de user agent não são confiáveis para determinar capacidades de entrada. Elas identificam o navegador e sistema operacional, não o hardware. Um laptop Windows e um tablet Windows podem compartilhar a mesma string de user agent apesar de terem métodos de entrada muito diferentes. Detecção de recursos através de maxTouchPoints ou media queries CSS é muito mais precisa.

Posso detectar se um usuário está usando toque ou mouse no momento?

Sim. A API Pointer Events fornece uma propriedade pointerType em eventos como pointerdown. Seu valor é touch, mouse ou pen dependendo da entrada sendo usada naquele momento. Isso é mais útil do que uma verificação única de capacidade, especialmente em dispositivos híbridos onde os usuários alternam entre entradas.

Qual é a diferença entre as media queries CSS pointer e any-pointer?

A media query pointer segmenta apenas o dispositivo de entrada primário. A query any-pointer retorna verdadeiro se qualquer entrada disponível corresponder à condição. Em um laptop com trackpad e tela sensível ao toque, pointer coarse pode ser falso porque o trackpad é primário, mas any-pointer coarse seria verdadeiro porque a tela sensível ao toque se qualifica.

Open-source session replay

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.