JavaScript mapeo de eventos táctiles a eventos de ratón


Estoy usando el control deslizante de YUI que funciona con eventos de movimiento del ratón. Quiero que responda a los eventos touchmove (iPhone y Android). ¿Cómo puedo producir un evento de movimiento del ratón cuando se produce un evento touchmove? Espero que simplemente agregando algún script en la parte superior que los eventos touchmove se asignarán a los eventos de movimiento del ratón y no tendré que cambiar nada con el control deslizante.

Author: Questioner, 2009-10-05

5 answers

Estoy seguro de que esto es lo que quieres:

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);    
}

He capturado los eventos táctiles y luego he disparado manualmente mis propios eventos del ratón para que coincidan. Aunque el código no es particularmente de propósito general, debería ser trivial adaptarse a la mayoría de las bibliotecas de arrastrar y soltar existentes, y probablemente a la mayoría del código de eventos del ratón existente. Esperemos que esta idea sea útil para las personas que desarrollan aplicaciones web para el iPhone.

Actualización:

Al publicar esto, noté que llamar preventDefault en todos los eventos táctiles evitará que los enlaces funcionen correctamente. La razón principal para llamar a preventDefault es detener el desplazamiento del teléfono, y puede hacerlo llamándolo solo en la devolución de llamada touchmove. El único inconveniente de hacerlo de esta manera es que el iPhone a veces mostrará su ventana emergente sobre el origen de arrastre. Si descubro una manera de evitar eso, actualizaré este post.

Segunda Actualización:

He encontrado la propiedad CSS para desactivar la llamada: -webkit-touch-callout.

 99
Author: Mickey Shine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 17:59:55

Siguiendo las líneas de la respuesta de @Mickey Shine, Touch Punch proporciona mapeo de eventos táctiles para hacer clic en eventos. Está construido para poner este soporte en la interfaz de usuario de jQuery, pero el código es informativo.

 5
Author: Pat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-13 18:12:34

Para los futuros usuarios, que regresan aquí, se puede usar el siguiente código :

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];
    };
 };
})();

Y luego en los eventos use lo siguiente:

$(".yourDiv").on(eventMap.mouseup, function(event) {
      //your code
}
 3
Author: Pritam Banerjee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-21 13:58:24

Finalmente encontré una manera de hacer que esto funcione usando la solución de Mickey, pero en lugar de su función init. Utilice la función init aquí.

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 ves 'filter_div ' es el área del gráfico donde tenemos el filtro de rango del gráfico y solo en esa área queremos reescribir nuestros controles táctiles!

Gracias Mickey. Fue una gran solución.

 1
Author: Sana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-08 04:18:10

Para hacer que el código de @Mickey's funcione en Edge e Internet explorer, agregue las siguientes líneas.css del elemento donde desea que ocurra la simulación:

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

Estas líneas evitan el toque predeterminado para edge e IE. Pero si lo agrega al elemento incorrecto, también deshabilita scroll (que sucede de forma predeterminada en edge e IE en dispositivos táctiles).

 0
Author: kumardeepakr3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-01 16:49:51