preface

I wrote about a project where there was a requirement that looked something like this:

The home page needs to be in the form of a scrolling graph, that is, the user’s mouse for each scroll of the page corresponding to the page up or down.

When I heard about this requirement, I thought it was pretty simple, and given the time limit, I would write it by hand instead of using swiper.js.

No sooner said than done, the code starts clicking (in Chrome’s case) :

  • First, you need to listen to the mouse wheel scroll event to determine the direction of the scroll

    // Scroll events
    function handleMouseScroll(e) {
      const { wheelDelta } = e
      if (wheelDelta > 0) {
        console.log('Scroll up')}else if (wheelDelta < 0) {
        console.log('Scroll down')}}// Register events
    window.onmousewheel = handleMouseScroll
    Copy the code
  • Then, turn the page according to the scrolling direction

    // Total number of pages
    let pageTotal = 5
    // Current index
    let pageIndex = 0
    
    // Handle rolling events
    function handleMouseScroll(e) {
      const { wheelDelta } = e
      if (wheelDelta > 0) {
        // Scroll up
        if (pageIndex > 0) {
          pageIndex--
        } else {
          pageIndex = pageTotal
        }
      } else if (wheelDelta < 0) {
        // Scroll down
        if (pageIndex < pageTotal) {
          pageIndex++
        } else {
          pageIndex = 0}}// Test for correctness
      console.log(pageIndex)
    }
    
    // Register rolling events
    window.onmousewheel = handleMouseScroll
    Copy the code
  • Start testing after the page turn event is written. Scroll with the mouse, then open the console to see the result, and find that the output is as expected.

    1
    2
    3
    4
    5
    0
    1
    2
    3
    4
    5
    Copy the code

The result looks fine, but it is — I scroll down the mouse habitually and print many times in a row on the console. Shouldn’t it only be printed once, as we expect?

At this time I realized that the user is used to a scroll, in fact, “mouse” will quietly scroll several times, will trigger the corresponding many times of rolling events…

If you want to trigger the mouse wheel event only once, you need to be very careful with light scrolling. Such an experience clearly does not work 😂.

So in order to improve the experience, and to avoid excessive performance consumption, we need to use throttling or anti-shaking here.

Image stabilization

Debounce is the merging of a dense set of events into a single event. The popular definition is to fire an event frequently, but only once.

The so-called “intensive” is frequently triggered, so we need to set up a wait millisecond timer when the event is triggered for the first time to handle the subsequent frequent triggers. If it is fired again within that time period, the timer is cleared and the timer is reset until it is not fired again to execute the function passed in.

With this in mind, we can write a basic Debounce method. The first argument func is the original event handler, and the second argument wait is the wait time. The code is as follows:

/ * * *@param {Function} func The function to debounce.
 * @param {number} wait The number of milliseconds to delay.
 * @returns {Function} Returns a new function
 */
function debounce(func, wait) {
  let timer = null
  return function () {
    let args = arguments
    timer && clearTimeout(timer)
    timer = setTimeout(() = > {
      func.call(this. args) }, wait) } }Copy the code

With the method written, we can start testing:

// Register rolling events
window.onmousewheel = debounce(handleMouseScroll, 500)
Copy the code

After scrolling through the mouse for several times, open the console and see only one output, then we are done with this anti-shake.

1
Copy the code

The throttle

Throttling is to ensure that something is performed consistently every n milliseconds. The popular explanation is regular execution at regular intervals.

Similar to Debounce, it uses a timer. When an event is triggered for the first time, a timer is set to wait for milliseconds before executing the function passed in. The event triggered during the wait is ignored.

Again, by the way, we’ll write a basic throttle method. The first argument func is the original event handler, and the second argument wait is the wait time. The code is as follows:

/ * * *@param {Function} func The function to debounce.
 * @param {number} wait The number of milliseconds to delay.
 * @returns {Function} Returns a new function
 */
function throttle(func, wait) {
  let timer = null
  return function () {
    let args = arguments
    if(! timer) { timer =setTimeout(() = > {
        func.call(this. args) timer =null
      }, wait)
    }
  }
}
Copy the code

The above is the introduction and demonstration of anti-shake and throttling, friends can improve and test by themselves. Be sure to like 😘.