web-dev-qa-db-fra.com

Mappage JavaScript d'événements tactiles sur des événements de souris

J'utilise le curseur YUI qui fonctionne avec les événements de déplacement de la souris. Je souhaite le faire répondre aux événements touchmove (iPhone et Android). Comment créer un événement de déplacement de souris lorsqu'un événement touchmove se produit? J'espère qu'en ajoutant simplement un script en haut, les événements touchmove seront mappés aux événements de déplacement de la souris et que je n'aurai rien à changer avec le curseur. 

50
Questioner

Je suis sûr que c'est ce que vous voulez:

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
    switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type = "mousemove"; break;        
        case "touchend":   type = "mouseup";   break;
        default:           return;
    }

    // initMouseEvent(type, canBubble, cancelable, view, clickCount, 
    //                screenX, screenY, clientX, clientY, ctrlKey, 
    //                altKey, shiftKey, metaKey, button, relatedTarget);

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                                  first.screenX, first.screenY, 
                                  first.clientX, first.clientY, false, 
                                  false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() 
{
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);    
}

J'ai capturé les événements tactiles, puis activé manuellement les événements de souris correspondants. Bien que le code ne soit pas un objectif très général en tant que tel, il devrait être facile de s’adapter à la plupart des bibliothèques de glisser-déposer existantes et probablement au code d’événement de souris le plus existant. Espérons que cette idée sera utile aux personnes développant des applications Web pour iPhone.

Mettre à jour:

En publiant cela, j'ai remarqué que l'appel de preventDefault à tous les événements tactiles empêcherait les liens de fonctionner correctement. La raison principale d'appeler preventDefault est d'empêcher le téléphone de défiler. Vous pouvez le faire en l'appelant uniquement lors du rappel touchmove. Le seul inconvénient à le faire de cette façon est que l'iPhone affichera parfois son survol survol au-dessus de l'origine du glisser. Si je découvre un moyen d'éviter cela, je mettrai à jour ce post.

Deuxième mise à jour:

J'ai trouvé la propriété CSS pour désactiver la légende: -webkit-touch-callout.

101
Mickey Shine

Dans le sens de la réponse de @Mickey Shine, Touch Punch fournit un mappage des événements tactiles aux événements de clic. Il est conçu pour intégrer cette prise en charge dans l'interface utilisateur de jQuery, mais le code est informatif.

5
Pat

Pour les futurs utilisateurs, ceux qui reviennent ici peuvent utiliser le code suivant:

var eventMap = {};

(function(){
var eventReplacement = {
    "mousedown": ["touchstart mousedown", "mousedown"],
    "mouseup": ["touchend mouseup", "mouseup"],
    "click": ["touchstart click", "click"],
    "mousemove": ["touchmove mousemove", "mousemove"]
};


for (i in eventReplacement) {
    if (typeof window["on" + eventReplacement[i][0]] == "object") {
        eventMap[i] = eventReplacement[i][0];
    } 
    else {
        eventMap[i] = eventReplacement[i][1];
    };
 };
})();

Et puis, dans les événements, utilisez comme suit:

$(".yourDiv").on(eventMap.mouseup, function(event) {
      //your code
}
3
Pritam Banerjee

J'ai finalement trouvé un moyen de faire fonctionner cela en utilisant la solution de Mickey, mais au lieu de sa fonction init. Utilisez la fonction init ici.

function init() {
    document.getElementById('filter_div').addEventListener("touchstart", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchmove", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchend", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchcancel", touchHandler, true);
}

Si vous voyez «filter_div» est la zone de graphique où nous avons le filtre de plage de graphique et nous voulons uniquement réécrire nos contrôles tactiles dans cette zone!

Merci Mickey. C'était une excellente solution.

2
Sana

Pour que le code de @ Mickey fonctionne avec Edge et Internet Explorer, ajoutez les lignes suivantes dans le fichier .css de l'élément où vous souhaitez que la simulation se produise: 

.areaWhereSimulationHappens {
    overflow: hidden;
    touch-action: none;
    -ms-touch-action: none;
}

Ces lignes empêchent le contact par défaut pour Edge et IE. Mais si vous l'ajoutez au mauvais élément, il désactivera également le défilement (ce qui se produit par défaut sur Edge et IE sur les périphériques tactiles).

0
kumardeepakr3