2012-09-12 11 views
20

Me gustaría hacerlo de modo que a medida que arrastra su dedo sobre un conjunto de elementos, cambie el fondo del que tiene en su dedo.Cruzando a nuevos elementos durante el movimiento táctil

Parece que quiero usar el evento touchmove para esto, pero por lo que yo sé, el elemento objetivo nunca cambia, incluso cuando se arrastra. El clienteX y el clienteY cambian, y encontré esta función document.elementFromPoint que funciona en cromo, pero parece muy indirecta (además, no estoy seguro de qué navegadores lo admiten)

Ver este violín, quiero que las cajas se vuelvan verdes se toca a través de ellos:

http://jsfiddle.net/QcQYa/9/

Por cierto, en cromo, tendrá que ir a la pestaña de agente de usuario modal del inspector de configuración y elegir la opción "emular eventos de toque" para ver mi ejemplo.

Editar: me encontré con una idea de usar mouseenter aquí How to detect html elements on touchmove y se puso a trabajar en el cromo de escritorio, pero no en Safari Mobile.

+0

Tienes que mirar en las coordenadas de su evento touchmove y ver si se superponen con las coordenadas de tu elemento htmlTuve que escribir el mismo código para un juego de Android jquerymobile, no lo tengo aquí en casa, pero mañana puede buscarlo y actualizar tu violín con él. – Nelson

Respuesta

20

Me tomó un enfoque diferente:

Cada evento táctil puedo comprobar si la posición de contacto es dentro de un objeto $('.catch').

function highlightHoveredObject(x, y) { 
    $('.catch').each(function() { 
     // check if is inside boundaries 
     if (!(
      x <= $(this).offset().left || x >= $(this).offset().left + $(this).outerWidth() || 
      y <= $(this).offset().top || y >= $(this).offset().top + $(this).outerHeight() 
    )) { 

     $('.catch').removeClass('green'); 
     $(this).addClass('green'); 
     } 
    }); 
} 

Lo puede ver trabajando en jsFiddle.
Funciona en Chrome, espero que también lo haga en dispositivos móviles.

Editar:
En this fiddle que utiliza ambas versiones, la mía y que uno desde el enlace en los comentarios (document.elementFromPoint – a jQuery solution), ambos parecen trabajar en mi teléfono Android. También agregué un punto de referencia rápido y sucio (vea la consola) y como era de esperar document.elementFromPoint es unas milésimas más rápido, si esa es su preocupación, debe verificar el soporte de document.elementFromPoint para los navegadores que quiera admitir.

+0

parece que funciona, importa analizar esto vs 'document.elementFromPoint'? – spike

+0

Bueno, ciertamente la incompatibilidad del navegador es el mayor inconveniente. Encontré 2 artículos que pueden interesarle mucho: [document.elementFromPoint - a jQuery solution] (http://www.zehnet.de/2010/11/19/document-elementfrompoint-a-jquery-solution/) y [elementFromPoint() en iOS 5] (http://www.icab.de/blog/2011/10/17/elementfrompoint-under-ios-5/). Ahí también verá que tiene que calcular la ventana gráfica actual. No estoy seguro si lo mismo se aplica a mi solución. Para mí, mi solución parece menos dolorosa, pero depende de usted elegir –

+0

Lo que no pensé es que necesita dirigirse a navegadores de teléfono/tableta. Lamentablemente, no sé qué navegadores móviles son compatibles con 'document.elementFromPoint'. Pero creo que si todos los admiten, sería un ligero aumento en el rendimiento porque las funciones internas son más rápidas. –

0

No puede "desencadenar un evento touchend" o cancelar toques, que necesitaría para comenzar a tocar otro.

Así que sería mejor que vincule el evento touchmove al contenedor y manipule las cajas según su posición/tamaño y la posición táctil, como qué parte de la respuesta de Dan Lee hace.

2

Encontrará mi solución en this fiddle, he comprobado en mi teléfono Android y funciona bien, utiliza jquery mobile para aprovechar vmousemove caso, también attachs un manejador de eventos touchmove sólo para evitar el desplazamiento de la vista del navegador en el dispositivo móvil.

me pegue aquí el código HTML correspondiente y javascript trozos:

<div id="main" ontouchmove="touchMove(event);"> 
    <span class='catch'>One</span> 
    <span class='catch'>Two</span> 
    <span class='catch'>Three</span> 
    <span class='catch'>Four</span> 
    <span class='catch'>Five</span> 
    <span class='catch'>Six</span> 
    <span class='catch'>Seven</span> 
</div> 

ahora el javascript:

function elem_overlap(jqo, left, top) { 
    var d = jqo.offset(); 
    return top >= d.top && left >= d.left && left <= (d.left+jqo[0].offsetWidth) 
      && top <= (d.top+jqo[0].offsetHeight); 
} 

/* To prevent WebView from scrolling on swipe, see http://goo.gl/DIZbm */ 
touchMove = function(event) { 
    event.preventDefault(); //Prevent scrolling on this element 
} 

$("#main").bind("vmousemove", function(evt){ 
    $('.catch').each(function(index) { 
     if (elem_overlap($(this), evt.pageX, evt.pageY)) { 
     $('.catch').not('eq('+index+')').removeClass('green'); 
     if (!$(this).hasClass('green')) { 
      $(this).addClass('green'); 
     } 
     } 
    }); 
}); 
+0

Gracias por esta solución diferente. Todavía no uso jquery mobile, pero parece que funciona bien. – spike

Cuestiones relacionadas