variable quitar problema isnan error ejemplo como carga asincrona javascript jquery html dom scroll

quitar - problema nan javascript



¿Es posible determinar donde un rollo terminará usando javascript? ¿Si es así, cómo? (3)

Como lo indica @seahorsepip, generalmente no es posible saber dónde terminará un desplazamiento sin agregar un comportamiento personalizado con JavaScript. Los documentos de MDN no enumeran ninguna forma de acceder a eventos de desplazamiento en cola: https://developer.mozilla.org/en-US/docs/Web/Events/scroll

Encontré esta información útil: Normalizando la velocidad de la rueda del mouse en los navegadores

Resalta la dificultad de saber dónde irá la página en función de las aportaciones del usuario. Mi sugerencia es activar un evento de desplazamiento hacia Y cuando el código predice que se alcanza el umbral. En su ejemplo, si el desplazamiento ha movido la página 800 de 1000 píxeles en una ventana de tiempo de 250 ms, establezca el desplazamiento en esa marca de 1000 píxeles y corte el desplazamiento durante 500 ms.

https://developer.mozilla.org/en-US/docs/Web/API/window/scrollTo

Tengo una situación en la que, por ejemplo, si el desplazamiento de un usuario produce un cambio de 1000 px en scrollTop, me gustaría saberlo antes de tiempo.

El ejemplo perfecto es el control de iCalendar sobre el desplazamiento de un usuario. No importa lo difícil que se desplace en la aplicación iCalendar, lo más lejos que pueda desplazarse será el mes siguiente o el anterior.

Actualmente tengo una solución muy complicada para limitar el comportamiento del desplazamiento, que solo tiene en cuenta dónde está actualmente el desplazamiento del usuario.

MyConstructor.prototype._stopScroll = function(){ //Cache the previous scroll position and set a flag that will control //whether or not we stop the scroll var previous = this._container.scrollTop; var flag = true; //Add an event listener that stops the scroll if the flag is set to true this._container.addEventListener(''scroll'', function stop(){ if(flag) { this._container.scrollTop = previous; } }.bind(this), false); //Return a function that has access to the stop function and can remove it //as an event listener return function(){ setTimeout(function(){ flag = false; this._container.removeEventListener(''scroll'', stop, false); }.bind(this), 0); }.bind(this); };

Este enfoque funciona y detendrá un desplazamiento en progreso, pero no es fluido y me encantaría saber si hay una mejor manera de lograrlo.

La clave de esta pregunta es si puedo saber de antemano dónde terminará un rollo. ¡¡¡Gracias!!!


Edición: Acabo de encontrar el siguiente proyecto en github:

https://github.com/jquery/jquery-mousewheel

Probé la demostración y puedo informar la velocidad de desplazamiento de mi touchpad y mouse. También es capaz de detener el desplazamiento sin ninguna posición fija hacks: D

Voy a echar un vistazo en los próximos días y ver si puedo escribir algo que informe sobre la velocidad de desplazamiento, la dirección, la velocidad, el dispositivo, etc. Con suerte, podré crear algún complemento de jQuery que pueda anular toda interacción de desplazamiento.

Actualizaré esta publicación cuando tenga más información sobre este tema.

Es imposible predecir dónde terminará un desplazamiento del mouse.

Por otro lado, un deslizador de pantalla táctil / panel táctil tiene una cierta velocidad que disminuirá después de que el usuario deje de deslizar el dedo, como un automóvil que recibió un empujón y luego comienza a disminuir la velocidad.

Lamentablemente, cada navegador / os / driver / touchscreen / touchpad / etc tiene su propia implementación para esa parte de desaceleración, por lo que no podemos predecir eso.


Pero, por supuesto, podemos escribir nuestra propia implementación.

Tenemos 3 implementaciones que se podrían hacer:

Una dirección

B. Dirección y velocidad.

C. Dirección, velocidad y velocidad.


iCalender probablemente usa la implementación A.


Implementación A:

Envía la dirección de desplazamiento a la consola, el usuario puede desplazarse +/- 1px antes de que se detecte la dirección.

Demo en JSFiddle

Demo con animación en JSFiddle

(function iDirection() { var preventLoop = true; var currentScroll = scrollTop(); function scroll() { if(preventLoop) { //Get new scroll position var newScroll = scrollTop(); //Stop scrolling preventLoop = false; freeze(newScroll); //Check direction if(newScroll > currentScroll) { console.log("scrolling down"); //scroll down animation here } else { console.log("scrolling up"); //scroll up animation here } /* Time in milliseconds the scrolling is disabled, in most cases this is equal to the time the animation takes */ setTimeout(function() { //Update scroll position currentScroll = newScroll; //Enable scrolling unfreeze(); /* Wait 100ms before enabling the direction function again (to prevent a loop from occuring). */ setTimeout(function() { preventLoop = true; }, 100); }, 1000); } } $(window).on("scroll", scroll); })();


Implementación B:

Envía la dirección de desplazamiento, la distancia y la velocidad promedio a la consola, el usuario puede desplazar la cantidad de píxeles establecidos en la variable de distance .

Sin embargo, si el usuario se desplaza rápidamente, podrían desplazarse unos pocos píxeles más.

Demo en JSFiddle

(function iDirectionSpeed() { var distance = 50; //pixels to scroll to determine speed var preventLoop = true; var currentScroll = scrollTop(); var currentDate = false; function scroll() { if(preventLoop) { //Set date on scroll if(!currentDate) { currentDate = new Date(); } //Get new scroll position var newScroll = scrollTop(); var scrolledDistance = Math.abs(currentScroll - newScroll); //User scrolled `distance` px or scrolled to the top/bottom if(scrolledDistance >= distance || !newScroll || newScroll == scrollHeight()) { //Stop scrolling preventLoop = false; freeze(newScroll); //Get new date var newDate = new Date(); //Calculate time var time = newDate.getTime() - currentDate.getTime(); //Output speed console.log("average speed: "+scrolledDistance+"px in "+time+"ms"); /* To calculate the animation duration in ms: x: time y: scrolledDistance z: distance you''re going to animate animation duration = z / y * x */ //Check direction if(newScroll > currentScroll) { console.log("scrolling down"); //scroll down animation here } else { console.log("scrolling up"); //scroll up animation here } /* Time in milliseconds the scrolling is disabled, in most cases this is equal to the time the animation takes */ setTimeout(function() { //Update scroll position currentScroll = newScroll; //Unset date currentDate = false; //Enable scrolling unfreeze(); /* Wait 100ms before enabling the direction function again (to prevent a loop from occuring). */ setTimeout(function() { preventLoop = true; }, 100); }, 1000); } } } $(window).on("scroll", scroll); })();


Implementación C:

Envía la dirección de desplazamiento, la distancia y las velocidades a la consola, el usuario puede desplazar la cantidad de píxeles establecidos en la variable de distance .

Sin embargo, si el usuario se desplaza rápidamente, podrían desplazarse unos pocos píxeles más.

Demo en JSFiddle

(function iDirectionSpeedVelocity() { var distance = 100; //pixels to scroll to determine speed var preventLoop = true; var currentScroll = []; var currentDate = []; function scroll() { if(preventLoop) { //Set date on scroll currentDate.push(new Date()); //Set scrollTop on scroll currentScroll.push(scrollTop()); var lastDate = currentDate[currentDate.length - 1]; var lastScroll = currentScroll[currentScroll.length - 1]; //User scrolled `distance` px or scrolled to the top/bottom if(Math.abs(currentScroll[0] - lastScroll) >= distance || !lastScroll || lastScroll == scrollHeight()) { //Stop scrolling preventLoop = false; freeze(currentScroll[currentScroll.length - 1]); //Total time console.log("Time: "+(lastDate.getTime() - currentDate[0].getTime())+"ms"); //Total distance console.log("Distance: "+Math.abs(lastScroll - currentScroll[0])+"px"); /* Calculate speeds between every registered scroll (speed is described in milliseconds per pixel) */ var speeds = []; for(var x = 0; x < currentScroll.length - 1; x++) { var time = currentDate[x + 1].getTime() - currentDate[x].getTime(); var offset = Math.abs(currentScroll[x - 1] - currentScroll[x]); if(offset) { var speed = time / offset; speeds.push(speed); } } //Output array of registered speeds (milliseconds per pixel) console.log("speeds (milliseconds per pixel):"); console.log(speeds); /* We can use the array of speeds to check if the speed is increasing or decreasing between the first and last half as example */ var half = Math.round(speeds.length / 2); var equal = half == speeds.length ? 0 : 1; var firstHalfSpeed = 0; for(var x = 0; x < half; x++ ) { firstHalfSpeed += speeds[x]; } firstHalfSpeed /= half; var secondHalfSpeed = 0; for(var x = half - equal; x < speeds.length; x++ ) { secondHalfSpeed += speeds[x]; } secondHalfSpeed /= half; console.log("average first half speed: "+firstHalfSpeed+"ms per px"); console.log("average second half speed: "+secondHalfSpeed+"ms per px"); if(firstHalfSpeed < secondHalfSpeed) { console.log("conclusion: speed is decreasing"); } else { console.log("conclusion: speed is increasing"); } //Check direction if(lastScroll > currentScroll[0]) { console.log("scrolling down"); //scroll down animation here } else { console.log("scrolling up"); //scroll up animation here } /* Time in milliseconds the scrolling is disabled, in most cases this is equal to the time the animation takes */ setTimeout(function() { //Unset scroll positions currentScroll = []; //Unset dates currentDate = []; //Enable scrolling unfreeze(); /* Wait 100ms before enabling the direction function again (to prevent a loop from occuring). */ setTimeout(function() { preventLoop = true; }, 100); }, 2000); } } } $(window).on("scroll", scroll); })();


Funciones auxiliares utilizadas en las implementaciones anteriores:

//Source: https://github.com/seahorsepip/jPopup function freeze(top) { if(window.innerWidth > document.documentElement.clientWidth) { $("html").css("overflow-y", "scroll"); } $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top}); } function unfreeze() { $("html").css("position", "static"); $("html, body").scrollTop(-parseInt($("html").css("top"))); $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""}); } function scrollTop() { return $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop(); } function scrollHeight() { return $("html")[0].scrollHeight ? $("html")[0].scrollHeight : $("body")[0].scrollHeight; }

Solo eché un vistazo a scrollify mencionado en los comentarios, es de 10kb y necesita engancharse en cada evento simple: toque, desplazamiento del mouse, botones del teclado, etc.

Eso no parece ser una prueba de futuro, ¿quién sabe qué posible interacción del usuario puede causar un desplazamiento en el futuro?

El evento onscroll, por otro lado, siempre se activará cuando la página se desplace, así que simplemente enganchemos el código de animación en eso sin preocuparnos por la interacción del dispositivo de entrada.


No estoy muy seguro de si tengo lo que estás buscando. He tenido proyecto una vez, donde tuve que controlar el desplazamiento. En aquel entonces, he sobrescrito el evento de desplazamiento predeterminado, después de eso, puede establecer una distancia personalizada para el desplazamiento "uno". Además se agregaron animaciones jQuery para desplazarse a una posición específica. Aquí puedes echar un vistazo: http://c-k.co/zw1/ Si eso es lo que buscas, puedes contactarme y veré cuánto entiendo de mi propia cosa allí.