JS función de estabilización de imagen y el acelerador

Agitar

tecnología de estabilización de imagen que es más que puede ser invocado de forma secuencial combina en una sola, en un tiempo determinado para detener el funcionamiento de las disposiciones de eventos solamente se desencadenó una vez.

popular punto, echar un vistazo al siguiente ejemplo simplificado:

// 防抖动函数
function debounce (func, wait, immediate) {
    var timeout;
    return function () {
        var context = this, args = arguments;
        var later = function () {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
 
var myEfficientFn = debounce(function() {
    // 滚动中的真正的操作
}, 250);
 
// 绑定监听
window.addEventListener('resize', myEfficientFn);

Si las dos funciones es probable que no activación de un evento de desplazamiento continuo dentro de 250 ms, entonces podremos realmente queremos activar la función de disparo en caso de desplazamiento.

Estrangulación (Throttling)

La función anti-vibración muy buena, pero hay problemas, tales como la carga diferida de la imagen, espero que en el proceso de caer constantemente siendo cargado fuera de la imagen, y no sólo cuando dejó de caer cuando la imagen sólo se cargarlo. O la disminución de la solicitud Ajax cuando la carga de datos es la misma razón.

Esta vez, esperamos que incluso si la página se desplaza de forma continua, pero el manejador de desplazamiento también puede ser activado a una frecuencia determinada (por ejemplo, desencadenar una 250ms), este tipo de escenario, es necesario utilizar otra técnica, conocida como función de estrangulamiento (estrangulamiento ).

función de regulación, una función se ejecuta sólo una vez en los X milisegundos.

En comparación con estabilización de imagen, la diferencia principal función de gas es que garantiza la aplicación de al menos un controlador de eventos que queremos activación en X milisegundos.

En comparación con la estabilización de imagen, una expansión multi-función mustRun atributo representante de los milisegundos mustRun, inevitablemente desencadenar una Handler, utilizando el mismo temporizador para ver ejemplo sencillo

// 简单的节流函数
function throttle (func, wait, mustRun) {
    var timeout,
        startTime = new Date();
 
    return function () {
        var context = this,
            args = arguments,
            curTime = new Date();
 
        clearTimeout(timeout);
        // 如果达到了规定的触发时间间隔,触发 handler
        if(curTime - startTime >= mustRun){
            func.apply(context, args);
            startTime = curTime;
        // 没达到触发间隔,重新设定定时器
        } else {
            timeout = setTimeout(func, wait);
        }
    };
};
// 实际想绑定在 scroll 事件上的 handler
function realFunc(){
    console.log("Success");
}
// 采用了节流函数
window.addEventListener('scroll', throttle(realFunc,500,1000));

El ejemplo anterior una simple función del acelerador puede tratar de obtener el siguiente navegador, probablemente función es la de desplazamiento si alguna vez se ha activado el intervalo más corto que 500 ms, a continuación, queremos asegurarnos de que el controlador de eventos se invoca al menos una vez dentro de 1000 ms disparadores .

Uso rAF (requestAnimationFrame) evento desencadenante de desplazamiento

window.requestAnimationFrame () Este método se utiliza antes de la página se vuelve a dibujar, que le dice al navegador para llamar a una función especificada. Este método toma una función como un parámetro, la función será llamada antes de que el redibujado.

rAF utiliza comúnmente en la producción de animación web, para el marco de un control preciso actualizar la representación de la página, lo que permite la animación más fluida, por supuesto, su papel no se limita a la animación, podemos tomar ventaja de sus características como un temporizador. (Por supuesto, no es un contador de tiempo)

En términos generales, la frecuencia AFr se llama 60 veces por segundo, es decir desde 1000 hasta 1060, la frecuencia de activación es de aproximadamente 16.7ms. (Al realizar operaciones complejas, cuando se encuentra que sea imposible mantener la frecuencia de 60 fps, se reducirá la frecuencia para mantener número de marco estable 30 fps.)

var ticking = false; // rAF 触发锁
 
function onScroll(){
    if(!ticking) {
        requestAnimationFrame(realFunc);
        ticking = true;
    }
}
 
function realFunc(){
    // do something...
    console.log("Success");
    ticking = false;
}
// 滚动事件监听
window.addEventListener('scroll', onScroll, false);

Ejemplos de uso sencillo rAF anteriormente pueden tratar de obtener el siguiente navegador, probablemente, la función es en el proceso de implantación, el mantenimiento de una frecuencia de controlador de eventos 16.7ms gatillo.

ventajas y desventajas del uso de co-existir requestAnimationFrame, en primer lugar debemos tener en cuenta sus problemas de compatibilidad, y en segundo lugar, ya que sólo puede lograrse a una frecuencia de 16.7ms al gatillo, en nombre de su capacidad de ajuste es muy pobre. Sin embargo, en comparación con el acelerador (func, xx, 16.7), cuando se utiliza para los escenarios más complejos, RAF podría obtener mejores resultados y un mejor rendimiento.

resumen

rebote de anti-vibración: tecnología anti-vibración que es más que puede ser invocado combinarse secuencialmente en una sola, es decir, dentro de un cierto período de tiempo, se activan un número predeterminado de eventos.

estrangular la función de gas: Sólo una función a realizar en los X milisegundos, sólo cuando la última función ejecutada después de un intervalo de tiempo especificado que pueda para la siguiente llamada a la función.

requestAnimationFrame: 16.7ms desencadenan un manipulador, reducida capacidad de control, pero para mejorar el rendimiento y la precisión.

referencia

http://www.cnblogs.com/coco1s/p/5499469.html

Apéndice - otra biblioteca madura

Proporcionando más maduro subrayado la estabilización del acelerador función, véase más adelante

función anti-vibración

/**
 * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
 *
 * @param  {function} func        传入函数
 * @param  {number}   wait        表示时间窗口的间隔
 * @param  {boolean}  immediate   设置为ture时,调用触发于开始边界而不是结束边界
 * @return {function}             返回客户调用函数
 */
_.debounce = function (func, wait, immediate) {
    var timeout, args, context, timestamp, result;

    var later = function () {
        // 据上一次触发时间间隔
        var last = _.now() - timestamp;

        // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function () {
        context = this;
        args = arguments;
        timestamp = _.now();
        var callNow = immediate && !timeout;
        // 如果延时不存在,重新设定延时
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
};

la función del acelerador

/**
 * 频率控制 返回函数连续调用时,func 执行频率限定为 次 / wait
 * 
 * @param  {function}   func      传入函数
 * @param  {number}     wait      表示时间窗口的间隔
 * @param  {object}     options   如果想忽略开始边界上的调用,传入{leading: false}。
 *                                如果想忽略结尾边界上的调用,传入{trailing: false}
 * @return {function}             返回客户调用函数   
 */
_.throttle = function (func, wait, options) {
    var context, args, result;
    var timeout = null;
    // 上次执行时间点
    var previous = 0;
    if (!options) options = {};
    // 延迟执行函数
    var later = function () {
        // 若设定了开始边界不执行选项,上次执行时间始终为0
        previous = options.leading === false ? 0 : _.now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
    };
    return function () {
        var now = _.now();
        // 首次执行时,如果设定了开始边界不执行选项,将上次执行时间设定为当前时间。
        if (!previous && options.leading === false) previous = now;
        // 延迟执行时间间隔
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        // 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口
        // remaining大于时间窗口wait,表示客户端系统时间被调整过
        if (remaining <= 0 || remaining > wait) {
            clearTimeout(timeout);
            timeout = null;
            previous = now;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
            //如果延迟执行不存在,且没有设定结尾边界不执行选项
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
};

Supongo que te gusta

Origin www.cnblogs.com/everlose/p/12501229.html
Recomendado
Clasificación