Tenho alguns menus css no meu site que se expandem com :hover
(sem js)
Isso funciona de forma semi-quebrada em iDevices, por exemplo, um toque ativará a :hover
regra e expandirá o menu, mas tocar em outro lugar não remove o :hover
. Além disso, se houver um link dentro do elemento que está :hover
inserido, você deve tocar duas vezes para ativar o link (o primeiro toque aciona :hover
, o segundo toque aciona o link).
Consegui fazer as coisas funcionarem bem no iphone vinculando o touchstart
evento.
O problema é que às vezes o safari móvel ainda escolhe acionar a :hover
regra do css em vez de meus touchstart
eventos!
Eu sei que este é o problema porque quando eu desabilito todas as :hover
regras manualmente no css, o safari móvel funciona muito bem (mas os navegadores regulares obviamente não funcionam mais).
Existe uma maneira de "cancelar" :hover
regras dinamicamente para certos elementos quando o usuário está em um safári móvel?
Veja e compare o comportamento do iOS aqui: http://jsfiddle.net/74s35/3/ Observação: apenas algumas propriedades css acionam o comportamento de dois cliques, por exemplo, display: none; mas não fundo: vermelho; ou decoração de texto: sublinhado;
fonte
Respostas:
Descobri que ": hover" é imprevisível no Safari do iPhone / iPad. Às vezes, tocar em um elemento torna esse elemento ": pairar", enquanto às vezes ele muda para outros elementos.
Por enquanto, eu só tenho uma aula "sem toque" no corpo.
E tenha todas as regras CSS com ": hover" abaixo de ".no-touch":
Em algum lugar da página, tenho javascript para remover a classe no-touch do corpo.
Isso não parece perfeito, mas funciona de qualquer maneira.
fonte
:hover
não é o problema aqui. Safari para iOS segue uma regra muito estranha. Ele disparamouseover
emousemove
primeiro; se algo for alterado durante esses eventos, 'clique' e os eventos relacionados não serão disparados:mouseenter
emouseleave
parecem estar incluídos, embora não sejam especificados no gráfico.Se você modificar qualquer coisa como resultado desses eventos, os eventos de clique não serão disparados. Isso inclui algo mais acima na árvore DOM. Por exemplo, isso impedirá que cliques únicos funcionem em seu site com jQuery:
Edit: Para esclarecimento, o
hover
evento do jQuery incluimouseenter
emouseleave
. Ambos irão prevenirclick
se o conteúdo for alterado.fonte
hover
manipulador jquery estava evitando que umclick
manipulador separado fosse atingido - que piada!mouseenter
jsbin.com/maseti/5/edit?html,js,outputO Modernizer da biblioteca de detecção de recursos do navegador inclui uma verificação de eventos de toque.
Seu comportamento padrão é aplicar classes ao seu elemento html para cada recurso detectado. Você pode então usar essas classes para definir o estilo do seu documento.
Se os eventos de toque não estiverem ativados, a Modernizr pode adicionar uma classe de
no-touch
:E então escopo seus estilos de foco com esta classe:
Você pode baixar uma versão customizada do Modernizr para incluir o mínimo ou o número de detecções de recursos que você precisar.
Aqui está um exemplo de algumas classes que podem ser aplicadas:
fonte
Alguns dispositivos (como outros já disseram) têm eventos de toque e mouse. O Microsoft Surface, por exemplo, tem uma tela sensível ao toque, um trackpad E uma caneta que realmente gera eventos de foco quando é pairado acima da tela.
Qualquer solução que desabilite com
:hover
base na presença de eventos de 'toque' também afetará os usuários do Surface (e muitos outros dispositivos semelhantes). Muitos novos laptops são sensíveis ao toque e responderão a eventos de toque - então, desativar o foco é uma prática realmente ruim.Este é um bug no Safari, não há absolutamente nenhuma justificativa para este terrível comportamento. Recuso-me a sabotar navegadores que não sejam iOS por causa de um bug no iOS Safari que aparentemente existe há anos. Eu realmente espero que eles corrijam isso para iOS8 na próxima semana, mas enquanto isso ...
Minha solução :
Alguns já sugeriram o uso do Modernizr, bem, o Modernizr permite que você crie seus próprios testes. O que estou basicamente fazendo aqui é 'abstrair' a ideia de um navegador compatível
:hover
com um teste Modernizr que posso usar em todo o meu código sem codificar totalmenteif (iOS)
.Então o css se torna algo assim
Apenas no iOS esse teste falhará e desabilitará o rollover.
A melhor parte dessa abstração é que se eu descobrir que ele quebra em um determinado Android ou se for corrigido no iOS9, posso apenas modificar o teste.
fonte
html:not(.no-hover) .category:hover { ...
Adicionar a biblioteca FastClick à sua página fará com que todos os toques em um dispositivo móvel sejam transformados em eventos de clique (independentemente de onde o usuário clica), portanto, também deve corrigir o problema de foco em dispositivos móveis. Eu editei seu violino como exemplo: http://jsfiddle.net/FvACN/8/ .
Basta incluir a lib fastclick.min.js em sua página e ativar via:
Como um benefício colateral, ele também removerá o atraso onClick irritante de 300ms que os dispositivos móveis sofrem.
Existem algumas consequências menores no uso do FastClick que podem ou não ser importantes para o seu site:
fonte
Uma solução melhor, sem qualquer JS, classe css e verificação de janela de visualização: você pode usar os recursos do Interaction Media (Media Queries Nível 4)
Como isso:
iOS Safari suporta
Mais sobre: https://www.jonathanfielding.com/an-introduction-to-interaction-media-features/
fonte
Existem basicamente três cenários:
:hover
:hover
elementosA resposta aceita originalmente funciona muito bem se apenas os dois primeiros cenários forem possíveis, em que um usuário tem um ponteiro ou uma tela sensível ao toque. Isso era comum quando o OP fez a pergunta há 4 anos. Vários usuários apontaram que os dispositivos Windows 8 e Surface estão tornando o terceiro cenário mais provável.
A solução iOS para o problema de não ser capaz de pairar em dispositivos touchscreen (conforme detalhado por @Zenexer) é inteligente, mas pode fazer com que um código simples não funcione corretamente (conforme observado pelo OP). Desativar o foco apenas para dispositivos com tela de toque significa que você ainda precisará codificar uma alternativa amigável com tela de toque. Detectar quando um usuário tem o ponteiro e a tela sensível ao toque turva ainda mais as águas (conforme explicado por @Simon_Weaver).
Neste ponto, a solução mais segura é evitar o uso
:hover
como a única maneira de um usuário interagir com seu site. Os efeitos de focalização são uma boa maneira de indicar que um link ou botão pode ser acionado, mas o usuário não deve ser obrigado a passar o mouse sobre um elemento para executar uma ação em seu site.Repensar a funcionalidade “hover” com telas sensíveis ao toque em mente traz uma boa discussão sobre abordagens alternativas de UX. As soluções fornecidas pela resposta incluem:
No futuro, esta provavelmente será a melhor solução para todos os novos projetos. A resposta aceita é provavelmente a segunda melhor solução, mas certifique-se de levar em consideração os dispositivos que também possuem dispositivos apontadores. Tenha cuidado para não eliminar a funcionalidade quando um dispositivo tem uma tela sensível ao toque apenas para contornar o
:hover
hack do iOS .fonte
A versão JQuery em seu .css usa .no-touch .my-element: hover para todas as suas regras de hover incluem JQuery e o seguinte script
Em seguida, no corpo da tag, adicione class = "no-touch" ontouchstart = "removeHoverState ()"
assim que o ontouchstart dispara, a classe para todos os estados de foco é removida
fonte
Em vez de apenas ter efeitos de flutuação quando o toque não está disponível, criei um sistema para lidar com eventos de toque e isso resolveu o problema para mim. Primeiro, defini um objeto para teste de eventos de "toque" (equivalente a "clique").
Então, em meu manipulador de eventos, faço algo como o seguinte:
fonte
Obrigado @Morgan Cheng pela resposta, no entanto, modifiquei ligeiramente a função JS para obter o " touchstart " (código retirado da resposta de @Timothy Perez ), no entanto, você precisa do jQuery 1.7+ para isso
fonte
Dada a resposta fornecida pelo Zenexer, um padrão que não requer tags HTML adicionais é:
Este método dispara primeiro o mouseover, depois o clique.
fonte
Concordo que desativar o foco para toque é o caminho a percorrer.
No entanto, para evitar o trabalho de reescrever seu css, basta embrulhar todos os
:hover
itens@supports not (-webkit-overflow-scrolling: touch) {}
fonte
Para aqueles com o caso de uso comum de desabilitar
:hover
eventos no iOS Safari, a maneira mais simples é usar uma consulta de mídia de largura mínima para seus:hover
eventos que fica acima da largura da tela dos dispositivos que você está evitando. Exemplo:fonte
Basta olhar para o tamanho da tela ....
fonte
aqui está o código em que você deseja colocá-lo
fonte