[] JavaScript siga subrayado la escuela del acelerador

estrangulación

Estrangulando principio es simple:

Si continúa eventos de activación, de vez en cuando, realizado sólo una vez evento.

De acuerdo con la primera vez si, y si el extremo, el efecto es diferente, la forma de conseguir diferentes.
¿Estamos por primera vez para llevar a cabo con los representantes principales, si éstas se realizan una vez más después de que el representante de arrastre.

Acerca de la limitación, hay dos implementaciones principales, una es utilizar las marcas de tiempo , uno es para configurar el temporizador .

El uso de marcas de tiempo

Veamos primer método: el uso de marcas de tiempo, cuando el evento desencadenante, que retire la fecha y hora actual y la marca de tiempo (más valor inicial se establece en 0) antes de restar, si es mayor que el período de tiempo establecido, sobre la aplicación de la función, y luego actualizar la marca de tiempo para la fecha y hora actual, si es inferior a, no se ejecuta.

Leer esta expresión, no se siente listo para escribir código ...... Vamos a escribir la primera versión del código:

function throttle(func, wait) {
    var self
    ,args
    ,previous = 0
    ,now;

    return function() {
        now = +new Date();
        context = this;
        args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

var container= document.getElementById('box');
var num = 1;
function addNum(){
    container.innerHTML = num++;
}

Ejemplos de todavía está hablando de supresión de rebotes (código HTML), entonces nos llaman:

container.addEventListener('mousemove',throttle(addNum,1000));
container.addEventListener('mouseleave',function(){
    container.innerHTML = '';
    num = 1;
});

Código análisis (Core):

  1. Y un código de posicionamiento soluciona este nodo DOM actual argumentos de coma;
  2. a cambio de la devolución de llamada lógica addEventListener escuchar a los eventos, por lo que hay esto y discusiones con la persona que llama es el cuadro actual;

La demostración es la siguiente:
Aquí Insertar imagen Descripción
podemos ver: cuando el ratón se mueve, el evento inmediatamente ejecutados, cada 1s se ejecutará una vez, si se detiene en 4.2s gatillo, no sería ejecutado eventos.

Uso del temporizador

A continuación, se habla de la segunda aplicación, mediante un temporizador.

Cuando el evento desencadenante, establecimos un temporizador, y luego eventos de disparo cuando el temporizador si no se ejecuta hasta que el contador de tiempo para llevar a cabo, y luego realizar una función, borrar el contador de tiempo, lo que puede establecer la siguiente temporizador.

// 第二版
var timeout;
function throttle(func, wait) {
    var context
    ,args  ;
    
    return function() {
        context = this;
        args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, wait)
        }
    }
}

Que llamamos de esta manera:

var container= document.getElementById('box');
var num = 1;

function addNum(){
    container.innerHTML = num++;
}

function clearNum(){
    if(!timeout){
        container.innerHTML = '';
        num = 1;
    }
}
function clear(func,wait){
    return function(){
        timer = setTimeout(() =>{
            timer = null;
            func.apply(this,arguments)
        },wait)
    }
   
}

container.addEventListener('mousemove',throttle(addNum,3000));
container.addEventListener('mouseleave',clear(clearNum,3000));

Para hacer el efecto más obvio, nos fijamos el tiempo de espera es 3s, efecto de demostración es la siguiente:
Aquí Insertar imagen Descripción
podemos ver: cuando el ratón se mueve, no se ejecutará el evento inmediatamente brilló después de 3s finalmente ejecutados una vez, luego cada 3 segundos una vez, cuando la pantalla digital como un tiempo de 3 removido inmediatamente desde el ratón, el equivalente de aproximadamente 9.2s cuando la detiene gatillo, pero todavía ejecutar un evento en los primeros 12 años de la época.

Así que la comparación de los dos métodos (fecha y hora) || temporizador:

El primer evento se ejecutará inmediatamente, el segundo evento será la primera ejecución después de n segundos
hay manera de detener después de la primera evento de disparo y luego ejecutar el evento, el segundo parada después del evento de disparo será todavía realizar otro evento

enfoque de dos vías

Que queremos de qué tipo?

Algunas personas dicen: Quiero un tener una cabeza, cola! El ratón se mueve pueda ejecutarse inmediatamente detendrá cuando el gatillo se puede realizar una vez más!

Por lo tanto hemos integrado las ventajas de ambos, el enfoque luego dos frentes, escribir una versión del código:

// 第三版
function throttle(func, wait) {
    var timeout, context, args, result;
    var previous = 0;

    var later = function() {
        previous = +new Date();
        timeout = null;
        func.apply(context, args)
    };

    var throttled = function() {
        var now = +new Date();
        //下次触发 func 剩余的时间
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
         // 如果没有剩余的时间了或者你改了系统时间
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
        } else if (!timeout) {
            timeout = setTimeout(later, remaining);
        }
    };
    return throttled;
}

La demostración es la siguiente:
Aquí Insertar imagen Descripción
podemos ver: el ratón en el evento e inmediatamente ejecutados, chapados 3s, el evento una vez más lleva a cabo cuando la hora digital se convierte en 3, es decir, después de 6s, hemos eliminado inmediatamente del ratón, el evento de fin de disparo, tiempo de 9s , todavía llevará a cabo otro evento.

optimización

Pero a veces me gustaría sin cabezas y las colas, o la cabeza sin cola, este país?

A continuación, hemos creado dos opciones como el tercer argumento, a continuación, emitir un juicio basado en el valor de qué tipo de efecto, al final, acordamos:

  • líder: falsas desactiva la primera ejecución
  • arrastra: falsos desables de devolución de llamada tope del disparador

Vamos a cambiar el código de abajo:

// 第四版
function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };

    var throttled = function() {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };
    return throttled;
}

cancelado

En la aplicación de eliminación de rebote, hemos añadido un método cancelar, el acelerador añadimos también un método cancelar:

// 第五版 非完整代码,完整代码请查看最后的演示代码链接
...
throttled.cancel = function() {
    clearTimeout(timeout);
    previous = 0;
    timeout = null;
}
...

prestar atención

Debemos tener en cuenta el guión bajo se dan cuenta que hay un problema de este tipo:

Que está llevando: falsa y finales: falso no se puede ajustar al mismo tiempo.

Si se establece, por ejemplo, cuando se mueve el ratón hacia fuera, ya que el conjunto de salida en falso, activador de detención cuando no está activado el temporizador, en tanto que otra hora determinada, y luego se trasladó, que sería ejecutado inmediatamente, una violación el principal: falsa, bicho salió, por lo que el acelerador sólo tres usos:

container.onmousemove = throttle(getUserAction, 1000);
container.onmousemove = throttle(getUserAction, 1000, {
    leading: false
});
container.onmousemove = throttle(getUserAction, 1000, {
    trailing: false
});

Ahora que hemos logrado un guión completo la función del acelerador, felicitaciones, Sahua!

La versión final del código

html:

<!DOCTYPE html>
<html lang="zh-cmn-Hans">

<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
    <title>throttle</title>
    <style>
    	#container{
            width: 100%;
            height: 200px;
            line-height: 200px;
            text-align: center;
            color: #fff;
            background-color: #444;
            font-size: 30px;
    	}
    </style>
</head>

<body>
	<div id="container"></div>
    <button id="button">点击取消debounce</button>
    <script src="throttle4.js"></script>
</body>

</html>

javascript:

/**
 * 第五版 添加取消方法 用法跟 debounce 相同
 */

var count = 1;
var container = document.getElementById('container');

function getUserAction() {
    container.innerHTML = count++;
};

var setUseAction = throttle(getUserAction, 10000);

container.onmousemove = setUseAction

document.getElementById("button").addEventListener('click', function(){
    setUseAction.cancel();
})

function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };

    var throttled = function() {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };

    throttled.cancel = function() {
        clearTimeout(timeout);
        previous = 0;
        timeout = null;
    };

    return throttled;
}

Lite acelerador Código

function throttle(fn) {
      let canRun = true; // 通过闭包保存一个标记
      return function () {
        if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
        canRun = false; // 立即设置为false
        setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
          fn.apply(this, arguments);
          // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
          canRun = true;
        }, 500);
      };
    }
    function sayHi(e) {
      console.log(e.target.innerWidth, e.target.innerHeight);
    }
    window.addEventListener('resize', throttle(sayHi));

La estabilización de imagen y escenarios de aplicación del acelerador

Aquí Insertar imagen Descripción

epílogo

sobre ~

Agitar hoplinks ↓

Mengchuo seguimiento subrayado estabilización de imagen de la escuela

Publicados 134 artículos originales · ganado elogios 80 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/Umbrella_Um/article/details/100923156
Recomendado
Clasificación