Skip to content

JavaScript之防抖节流 #16

@chenyong9528

Description

@chenyong9528

防抖

防抖的含义是指,事件的逻辑会在事件触发的一段时间后执行,如果在这段时间内重复触发该事件,那么事件的逻辑也会推迟执行(最后一次触发为准)。例如,click触发2s后我们会去执行它的逻辑,点击后2s内我们什么都不干,那么会如期而至,但在此期间我们反复点击,那么会以我们最后一次点击为准,之后2s再去执行事件的逻辑。

我们来实现一个这样的功能:

一个文本框绑定了input事件,触发1s后会把输入的值显示到p标签内,频繁输入以最后一次为准,和上面说的一样

const debounce = function(fn, t) {
  let timeout

  return function() {
    clearTimeout(timeout)
    timeout = setTimeout(fn.bind(this), t)
  }
}

const input = document.querySelector('input')
const msg = document.querySelector('p')

const handle = function() {
  msg.innerText = this.value
}

input.addEventListener('input', debounce(handle, 1000))

通过每次触发事件都清除定时器并安装一个新的定时器的方式,达到了我们的目的。但还有两个问题需要我们处理:

  1. 函数handle中不能获取event对象
  2. 我们可能想要在事件触发时立即执行一次handle,然后再恢复到某个时间一次

我们来改造debounce函数:

const debounce = function(fn, t, mark = true) {
  let timeout

  return function() {
    if (mark && !timeout) {
      fn.apply(this, arguments)
      timeout = 1
      return
    }

    clearTimeout(timeout)
    timeout = setTimeout(fn.bind(this, ...arguments), t)
  }
}

注意:上面的arguments是内部传入的,它只有一个元素就是event对象

通过传入可选的mark来决定是否立即执行一次事件的逻辑

同时,函数handle中也可以获取event对象

const handle = function(e) {
  msg.innerText = this.value
  console.log(e)
}

节流

节流是指,频繁触发的事件中,在一段时间内,只会执行一次事件逻辑。所以节流会稀释事件逻辑的执行频率,节省内存和cpu的开销。

我们实现两种节流方式:

  1. 立即执行一次
  2. 一段时间执行一次

第一种:

const throttle = (fn, t) => {
  let timeout

  return function() {
    if (timeout) return

    fn.apply(this, arguments)
    timeout = setTimeout(() => {
      timeout = null
    }, t)
  }
}

第二种:

const throttle = (fn, t) => {
  let timeout

  return function() {
    if (timeout) return

    timeout = setTimeout(() => {
      fn.apply(this, arguments)
      timeout = null
    }, t)
  }
}

这样使用:

const input = document.querySelector('input')
const msg   = document.querySelector('p')

const handle = function(e) {
  msg.innerText = this.value
  console.log(e)
}

input.addEventListener('input', throttle(handle, 1000))

两种主要区别是,第一种会立即执行一次,而第二种结束时还会执行一次,伪图形表示大概是这样:

|___|___|___|___|
|   |___|___|___|___|
|
|start

上面是第一种,下面是第二种,希望你能理解它的意思

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions