js防抖和节流

web开发中经常会做滚动监听,比如商品分类功能:左右两列,左侧类目,右侧商品,需要监听右测商品列表的滚动,滚到哪个类目区间,左侧就点亮哪个类目标签。如果在滚动的过程中一直监听而不做性能优化的话,浏览器是很容易卡死的。下面提供两种优化性能的方法:

1、防抖:在滚动过程中不执行操作,只在结束滚动一段时间内不再滚动才执行,这里的一段时间可以是500毫秒也可以是1秒,视具体业务而定。

// js防抖核心代码

function debounce (fn, delay) {
  let timer = null
  // 闭包
  return () => {
    // 如果当前正处在某个计时过程中,那么就清除此次计时开始下一次计时,
    // 否则不清除,直接开始下一次计时,计时满delay毫秒后才会触发fn函数。
    if (timer) {
      clearTimeout(timer)
    }
    // 开始下一次计时
    timer = setTimeout(fn, delay)
  }
}

function handleScroll () {
  console.log('滑动后一秒钟内不再滑动我就执行一次', Math.random())
}

window.addEventListener('scroll', debounce(handleScroll, 1000))

查看演示请狠狠地点击:js防抖demo

2、节流:如果希望即节省性能又不牺牲用户体验,就仍然在滚动中实时监听,只不过降低监听的“频率”,比如1秒才执行一次。下面提供两种实现方法(时间戳、定时器)。

// js节流核心代码

// 时间戳
function throttle1 (fn, delay) {
  let prev = Date.now()
  // 闭包
  return () => {
    let now = Date.now()
    if (now - prev >= delay) {
      fn()
      prev = Date.now()
    }
  }
}

// 定时器
function throttle2 (fn, delay) {
  let timer = null
  // 闭包
  return () => {
    if (!timer) {
      timer = setTimeout(() => {
        fn()
        timer = null
      }, delay)
    }
  }
}

function handleScroll () {
  console.log('滑动过程中我一秒钟才执行一次', Math.random())
}

window.addEventListener('scroll', throttle1(handleScroll, 1000))
// window.addEventListener('scroll', throttle2(handleScroll, 1000))

查看演示请狠狠地点击:js节流demo

你可能感兴趣的:(js防抖和节流)