美文网首页
再学JS--事件节流

再学JS--事件节流

作者: Territory_Cheng | 来源:发表于2020-07-17 11:14 被阅读0次

节流

节流:如果你持续触发事件,每隔一段时间,只执行一次事件

关于节流的实现,有两种主流的实现方式,一种是使用时间戳的方式,一种是设置定时器

使用时间戳

实现思路为:当触发条件的时候,我们取出当前的时间戳,然后减去之前的时间戳(初始化为0),如果大于设定的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于,则不执行

function throttle(func, wait) {
    var context, args
    var previous = 0

    return function() {
        var now = +new Date()
        context = this
        args = arguments

        if(now - previous > wait) {
            func.apply(context, args)
            previous = now
        }
    }
}

使用定时器

实现思路为:当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到定时器执行,然后执行函数,清空定时器,再设置下一个定时器

function throttle(func, wait) {
    var timeout
    var context, args

    return function() {
        context = this
        args = arguments
        if(!timeout) {
            timeout = setTimeout(function() {
                timeout = null
                func.apply(context, args)
            }, wait)
        }
    }
}

比较两种方法:

  1. 第一种事件会立即执行,第二种事件会在n秒后第一次执行
  2. 第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件

双剑合璧

鼠标移入能立即执行,停止触发的时候还能再执行一次

function throttle(func, wait) {
    var timeout, context, args, reslut
    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
}

优化

我们可增加一个参数options来约定:

  1. leading:false表示禁用第一次执行
  2. trailing:false表示禁用停止触发的回调
function throttle(func, wait, options) {
    var timeout, context, args, reslut
    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
        // 下次触发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)
            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
}

注意

如果同时设置 leading:falsetrailing:false,比如当你鼠标移出的时候,因为trailing设置为false,停止触发的时候不会设置定时器,所以只要再过了设置的时间,再移入的话,就会立即执行,就违反了leading:false,所以throttle只有三种用法:

throttle(func, 1000)
throttle(func, 1000, {leading:false})
throttle(func, 1000, {trailing:false})

相关文章

  • 再学JS--事件节流

    节流 节流:如果你持续触发事件,每隔一段时间,只执行一次事件 关于节流的实现,有两种主流的实现方式,一种是使用时间...

  • 再学JS--事件防抖

    在前端开发中会遇到一些频繁的事件触发,例如: window的resize、scroll mousedown、mou...

  • 再学JS--闭包

    MDN对闭包的定义: 闭包是指那些能够访问自由变量的函数 那什么是自由变量? 自由变量是指在函数中使用的,但既不是...

  • 再学js--变量对象

    当JavaScript代码执行一段可执行的代码时,会创建对应的执行上下文,对于每个执行上下文的创建阶段,都有三个重...

  • JS--事件

    DOM0 事件和DOM2级在事件监听使用方式上有什么区别? attachEvent与addEventListene...

  • 再学JS--数组去重

    双层循环 最原始的数组去重方式 indexOf 排序后去重 排序去去重是将数组进行sort排序,相同的值就会被排在...

  • 再学js--作用域链

    什么是作用域链? 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面的父级)执...

  • JS--事件对象

    在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。 DOM中的事件对...

  • JS--事件(一)

    事件流 事件流描述的是从页面中接受事件的顺序,在IE中的事件流是事件冒泡,在Netscape的事件流是事件捕获流。...

  • 再学JS--原型与原型链

    prototype 在JavaScript中,每一个函数都有一个prototype属性,且prototype属性是...

网友评论

      本文标题:再学JS--事件节流

      本文链接:https://www.haomeiwen.com/subject/gdtghktx.html