En el evento DOM del navegador, algunos eventos se activarán continuamente con las operaciones del usuario. Por ejemplo: cambie el tamaño de la ventana del navegador, desplácese la página del navegador y mouseMove. Es decir, cuando el usuario desencadena estas operaciones del navegador, si el método de manejo de eventos correspondiente está vinculado al script, este método se activará continuamente.
Esto no es lo que queremos, porque a veces si el método de manejo de eventos es relativamente grande, las operaciones DOM, como el complejo, y activar constantemente tales eventos causarán pérdidas de rendimiento, lo que dará como resultado una disminución en la experiencia del usuario (respuesta de interfaz de usuario lenta, navegador atascado, etc.). Por lo tanto, generalmente agregaremos lógica al evento correspondiente para retrasar la ejecución.
En términos generales, usamos el siguiente código para implementar esta función:
var count = 0; function testfn () {console.log (count ++); } // Cuando el navegador cambia de tamaño // 1. Borre el temporizador anterior // 2. Agregue un temporizador para retrasar la función real testfn por 100 milisegundos para activar ventana.onresize = function () {var timer = null; ClearTimeOut (temporizador); timer = setTimeOut (function () {testfn ();}, 100);};Los estudiantes cuidadosos descubren que el código anterior es realmente incorrecto. Este es un problema que los novatos hará: el valor de retorno de la función SetTimeOut debe guardar en una variable global relativa, de lo contrario, se generará un nuevo temporizador cada vez que se redimense el tamaño del tamaño, lo que no logrará el efecto que enviamos.
Entonces modificamos el código:
var timer = null; window.onresize = function () {cleartimeout (temporizador); timer = setTimeOut (function () {testfn ();}, 100);};En este momento, el código es normal, pero hay otro problema nuevo: se genera un temporizador variable global. Esto es algo que no queremos ver. Si esta página tiene otras funciones, también se llama temporizador. Los diferentes códigos causarán conflictos antes. Para resolver este problema, necesitamos usar una función de idioma de JavaScript: cierres de cierres. Los lectores pueden aprender sobre el conocimiento relacionado en MDN. El código modificado es el siguiente:
/*** Método de limitación de función* @param Fn Fn Letter Llamado Función* @param Número Retraso ¿Cuánto tiempo es el método de función de retraso? Función de retorno () {ClearTimeOut (temporizador); timer = setTimeOut (function () {fn ();}, demora); }}; window.onresize = Throttle (testfn, 200, 1000);Utilizamos una función de cierre (acelerador) para poner el temporizador internamente y devolver la función de procesamiento de retraso. De esta manera, la variable del temporizador es invisible para el exterior, pero también se puede acceder a la variable del temporizador cuando se activa la función de retraso interna.
Por supuesto, este método de escritura no es fácil de entender para los novatos. Podemos cambiar el método de escritura para comprender:
var del acelerador = function (fn, demora) {var timer = null; Función de retorno () {ClearTimeOut (temporizador); timer = setTimeOut (function () {fn ();}, demora); }}; var f = Throttle (testfn, 200); window.onresize = function () {f ();};Aquí hay un punto de vista: la función devuelta por el acelerador después de ser llamada es la función real que debe llamarse cuando se activa el OnResize
Ahora parece que este método está cerca de la perfección, pero no es el caso en el uso real. Por ejemplo:
Si el usuario cambia constantemente el tamaño de la ventana del navegador, la función de procesamiento de retraso no se ejecutará una vez
Por lo tanto, necesitamos agregar otra función: cuando el usuario cambia de tamaño, debe activarse al menos una vez dentro de un cierto período de tiempo. Dado que está dentro de un cierto período de tiempo, esta condición de juicio puede tomar los milisegundos de tiempo actual, y cada llamada de función resta el tiempo actual desde el último tiempo de llamada, y luego juzga que si la diferencia es mayor que un cierto período de tiempo, se enviará directamente, de lo contrario, aún seguirá la lógica de retraso de tiempo de espera.
Lo que hay que señalar en el siguiente código es:
1. La función de las variables anteriores es similar a la del temporizador. Ambos se registran el último identificador y deben ser variables globales relativas.
2. Si el proceso lógico sigue la lógica "activada al menos una vez", entonces la llamada de función debe completarse para restablecer la hora anterior a la hora actual. En pocas palabras, lo es: en comparación con la próxima última vez, en realidad es la actual.
/*** Método de limitación de función* @param FN FN DELATO Función de llamada* @param Retraso de número ¿Cuánto tiempo es el retraso* @param Número al menos cuánto tiempo se desencadena* @@return de la función Método para retrasar la ejecución*/var del acelerador = function (fn, demora, al menos) {var timer = null; var anterior = nulo; function de return () {var now = +new Date (); if (! anterior) anterior = ahora; if (ahora - anterior> al menos) {fn (); // reinicie la última hora de inicio a la hora final de este tiempo anterior = ahora; } else {ClearTimeOut (temporizador); timer = setTimeOut (function () {fn ();}, demora); }}};práctica:
Simulamos una escena de estrangulamiento cuando una ventana se desplaza, es decir, cuando el usuario se desplaza la página hacia abajo, necesitamos estrangular algunos métodos, como: calcular la posición DOM, etc., que requiere un funcionamiento continuo de elementos DOM.
El código completo es el siguiente:
<! Doctype html> <html lang = "en"> <fead> <meta charset = "utf-8"> <title> throttle </title> </head> <body> <div style = "altura: 5000px"> <Div Id = "Demo" Style = "Posición: fijo;"> </div> </div> <script> Var Count = 0, Demo = document.getElementById ('demo'); La función testfn () {Demo.innerhtml += 'testfn se llamó' ++ Count +'Time <br>';} var del acelerador = function (fn, demora, al menos) {var timer = null; var anterior = nulo; function de return () {var now = +new Date (); if (! anterior) anterior = ahora; if (al menos && ahora - anterior> al menos) {fn (); // reinicie la última hora de inicio a la hora final de este tiempo anterior = ahora; ClearTimeOut (temporizador); } else {ClearTimeOut (temporizador); timer = setTimeOut (function () {fn (); anterior = null;}, demora); }}}}; Window.onscroll = Throttle (Testfn, 200); // window.onscroll = Throttle (testfn, 500, 1000); </script> </body> </html>Usamos dos casos para probar el efecto, a saber, agregando al menos activar al menos el al menos y no agregar:
// case 1window.onscroll = Throttle (testfn, 200); // case 2window.onscroll = Throttle (Testfn, 200, 500);
El caso 1 se manifiesta como: TestFn no se llamará durante el proceso de desplazamiento de la página (no se puede detener), y se llamará una vez hasta que se detenga, lo que significa que el último asentamiento en el acelerador se ejecuta, y el efecto se muestra en la figura (ver la imagen GIF original):
El caso 2 se manifiesta como: durante el proceso de desplazamiento de la página (no se puede detener), TestFn se retrasará en 500 ms por primera vez (de al menos la lógica de retraso), y luego ejecutar al menos cada 500 ms, el efecto se muestra en la cifra
Hasta ahora, los resultados que queremos lograr se han completado básicamente. Los lectores pueden pensar en algunas optimizaciones auxiliares posteriores por sí mismos, como: Funcionar este punto, ahorro de valor de retorno, etc.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.