2012-10-04 11 views
9

Intento hacer un script de evento mousewheel, pero obtengo algunos problemas ya que estoy usando un Apple Magic Mouse y su función de continuar con el desplazamiento .Cómo comprobar cada nuevo desplazamiento y evitar el problema de los ratones de Apple (efecto de desplazamiento múltiple)

Quiero hacer esto http://jsfiddle.net/Sg8JQ/ (de jQuery Tools Scrollable with Mousewheel - scroll ONE position and stop, utilizando http://brandonaaron.net/code/mousewheel/demos), pero quiero una breve animación (como 250 ms) cuando se desplaza a las cajas, y la capacidad de Pasar por varios cuadros al desplazarse varias veces durante una animación. (Si me desplazo, la animación comienza a desplazarse al segundo cuadro, pero si me desplazo nuevamente, quiero ir al tercero, y si me desplazo dos veces, al cuarto, etc.)

Pensé por primera vez stopPropagation/preventDefault/return false; podría "detener" la velocidad de la rueda del mouse (y la var delta) - para que pueda contar el número de nuevos eventos de desplazamiento (tal vez con un temporizador) -, pero ninguno de ellos lo hace.

Ideas?

EDITAR: Si intenta desplazarse en Google Calendarios con estos mouses, se cambian varios calendarios, no solo uno. Parece que no pueden arreglar eso tampoco.

EDIT 2: Pensé en desenganchar la rueda del mouse y volver a unirla después de que pudiera detener el oyente de la rueda del mouse (y no escuchar el final de la inercia). No lo hizo.

Datos 3: trató de trabajar con fechas (gracias a this post), no es óptimo, pero mejor que nada http://jsfiddle.net/eZ6KE/

+1

Esto no será un problema solo en Magic Mice, pero todos los sistemas con desplazamiento de inercia (es decir, todas las Mac recientes, muchas PC más nuevas), su sugerencia de contar eventos de desplazamiento suena sensata y es posible que deba implementarla usted mismo. –

+0

Sí, tienes razón, es un problema de inercia (y estoy experimentando esto con mi Magic Mouse). Si contar eventos de desplazamiento suena como una buena solución, no tengo idea de cómo realizar esto. Intenté comprobar: en cada evento de desplazamiento (llamado cada vez durante la inercia) si el delta anterior era> o <, pero la curva no es lineal, es elástico en mi prueba. Algunas ideas ? (¡Gracias de todos modos!) – Joan

+0

Posible solución: https://github.com/brandonaaron/jquery-mousewheel/issues/36 (aún no probado). – Joan

Respuesta

0

tuve un problema similar en mi sitio web y después de muchos intentos fallidos, me escribió una función, que calculó la compensación total de la casilla seleccionada y comenzó la animación otra vez. Se veía así:

function getOffset() { 
    var offset = 0; 
    $("#bio-content").children(".active").prevAll().each(function (i) { 
     offset += $(this)[0].scrollHeight; 
    }); 
    offset += $("#bio-content").children(".active")[0].scrollHeight; 

    return offset; 
} 

var offset = getOffset(); 
$('#bio-content').stop().animate({ 
      scrollTop: offset 
}, animationTime); 

Espero que le dé una idea de cómo lograr lo que quiere.

+0

Debo estar malentendiendo, pero no veo cómo se puede solucionar el problema ... – Joan

+0

Por lo que entiendo, desea poder desplazarse de nuevo mientras se está produciendo la animación. ¿Estoy en lo cierto? Si es así, entonces lo que debe hacer es averiguar el desplazamiento de esa casilla en particular, desea desplazarse, detener la animación en curso e iniciar una nueva, que se desplazará al desplazamiento deseado. – Dygestor

+0

En realidad, el verdadero problema es la imposibilidad de detener el desplazamiento inercial una vez que lanzamos una animación. Ser capaz de lanzarlo de nuevo (una vez que detengamos la inercia, y si el usuario se desplaza nuevamente) es secundario. En su ejemplo, como en el mío, la animación se llamará varias veces para un desplazamiento debido a la inercia. – Joan

0

puede intentar detectar cuando la rueda deja de moverse, pero sería añadir un minuto de su tiempo de respuesta

$(document).mousewheel(function() { 
    clearTimeout($.data(this, 'timer')); 
    $.data(this, 'timer', setTimeout(function() { 
    alert("Haven't scrolled in 250ms!"); 
    //do something 
    }, 250)); 
}); 

fuente: jquery mousewheel: detecting when the wheel stops?

o implementar banderas evitando el inicio de una nueva animación

var isAnimating=false; 

$(document).bind("mousewheel DOMMouseScroll MozMousePixelScroll", function(event, delta) { 
    event.preventDefault(); 
    if (isAnimating) return; 
    navigateTo(destination); 
}); 

function navigateTo(destination){ 
    isAnimating = true; 
    $('html,body').stop().animate({scrollTop: destination},{complete:function(){isAnimating=false;}}); 
} 
1

La mejor manera es utilizar un tiempo de espera y verificar dentro del oyente si el tiempo de espera aún está activo:

var timeout = null; 
var speed = 100; //ms 
var canScroll = true; 

$(element).on('DOMMouseScroll mousewheel wheel', function(event) { 
    // Timeout active? do nothing 
    if (timeout !== null) { 
     event.preventDefault(); 
     return false; 
    } 

    // Get scroll delta, check for the different kind of event indexes regarding delta/scrolls 
    var delta = event.originalEvent.detail ? event.originalEvent.detail * (-120) : (
      event.originalEvent.wheelDelta ? event.originalEvent.wheelDelta : (
        event.originalEvent.deltaY ? (event.originalEvent.deltaY * 1) * (-120) : 0 
    )); 

    // Get direction 
    var scrollDown = delta < 0; 

    // This is where you do something with scrolling and reset the timeout 
    // If the container can be scrolling, be sure to prevent the default mouse action 
    // otherwise the parent container can scroll too 
    if (canScroll) { 
     timeout = setTimeout(function(){timeout = null;}, speed); 
     event.preventDefault(); 
     return false; 
    } 

    // Container couldn't scroll, so let the parent scroll 
    return true; 
}); 

Usted puede aplicar esto a cualquier elemento desplazable y en mi caso, he utilizado la biblioteca desplazable herramientas de jQuery, pero terminó en gran medida personalización para mejorar el apoyo del navegador, así como la adición de una funcionalidad personalizada específica al caso de uso.

Una cosa que debe tener cuidado es asegurarse de que el tiempo de espera sea lo suficientemente largo como para evitar que varios eventos se desencadenen sin problemas. Mi solución solo es efectiva si desea controlar la velocidad de desplazamiento de los elementos y cuántos deben desplazarse a la vez. Si agrega console.log(event) a la parte superior de la función de escucha y se desplaza utilizando un periférico de desplazamiento continuo, verá que se desencadenan muchos eventos de rueda del mouse.

un fastidio que el Firefox desplazarse DOMMouseScroll no desencadena el magic mouse o dispositivos de desplazamiento continuo, pero para los dispositivos de desplazamiento normales que tienen un desplazamiento y paro a través del ciclo de clic de la rueda del ratón.

Cuestiones relacionadas