2017-10-19 37 views
0

Donc, j'ai un problème. Je veux répondre à un utilisateur en appuyant sur le bouton de la souris (sur le bureau) ou en touchant un div (sur mobile). J'essaie d'être compatile avec les navigateurs à feuilles persistantes. C'est ce que j'ai essayé jusqu'à présent:Répondre au démarrage tactile et mousedown dans le bureau et le mobile, sans renifler

  • écoutez uniquement l'événement mouseDown. Cela fonctionne sur le bureau mais ne fonctionne pas dans le mobile si l'utilisateur fait glisser. Je veux que le gestionnaire soit appelé dès que l'utilisateur touche l'écran, peu importe s'il déplace son doigt dans le processus.
  • écoutez uniquement l'événement touchStart. Cela fonctionne sur les mobiles et les ordinateurs de bureau, à l'exception des ordinateurs de bureau Edge et Safari, qui ne prennent pas en charge les événements tactiles. Écoutez les deux, puis preventDefault. Cela entraîne un double appel sur Chrome mobile. Il semble que les événements tactiles sont passifs pour permettre un défilement ininterrompu sur Chrome mobile, donc preventDefualt n'a aucun effet sur eux. Ce que j'obtiens est un message d'avertissement disant "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080" dans la console, preventDefault est ignoré et mon événement est appelé deux fois.

Il est évident que cela peut être résolu en reniflant les événements tactiles, mais le filet est plein de coups de gueule pharisaïques sur la façon dont on doit être device-agnostic et que it's dangerous to detect touch events before the user interacted. Donc je suppose que la question est: est-il possible de faire ce que je veux faire sans renifler pour les événements tactiles?

Ci-dessous mon exemple React code:

function handler(e) { 
    console.log('handler called') 
    e.preventDefault() 
} 

export default function MyElement() { 
    return (
     <div 
      onMouseDown={handler} 
      onTouchStart={handler} 
     > 
     Hello 
     </div> 
    ) 
} 

Répondre

0

Il s'avérer it's not yet possible in React. Une solution de contournement est définie un indicateur la première fois que touchStart il est reçu.

touchHandler =() => { 
    this.useTouch = true 
    this.realHandler() 
} 

mouseHandler =() => { 
    if (this.useTouch) return 
    this.realHandler() 
} 

Avec la mise en garde que la première touchStart peut être perdu en cas de glissement.

Assez décevant.