DEV Community

HarmonyOS
HarmonyOS

Posted on

How to Intercept Multiple Rapid Click Events in Components ?

Read the original article:How to Intercept Multiple Rapid Click Events in Components ?

Problem Description

How to prevent multiple rapid clicks on a component from entering the same page?

Background Knowledge

The onClick() event triggers this callback when a click action occurs, and it can be triggered multiple times with multiple clicks. During development, there are scenarios where it is necessary to intercept the redirection of multiple clicks within a short period. There are two methods to achieve this:

  • Throttling: Runs only once within n seconds; if triggered repeatedly within n seconds, only the first trigger takes effect.
  • Debounce: Execute the event after n seconds; if triggered again within n seconds, reset the timer.

Troubleshooting Process

  1. Problem Analysis The issue is that rapid clicks on a component trigger multiple navigation events, leading to unintended behavior.
  2. Key Points Verification
    • Event Handling: The onClick() event is triggered multiple times with rapid clicks.
    • Navigation Control: The goal is to prevent multiple navigation attempts in a short time period.
  3. Solution Approach
    • Debouncing: Execute the navigation only once after a specified delay, ignoring repeated clicks during the delay.
    • Throttling: Limit the number of navigation executions within a specified time frame.

Analysis Conclusion

  1. Core Issue Rapid clicks trigger multiple navigation events, which can be disruptive.
  2. Fix Use debouncing or throttling to control the frequency of navigation events.
    • Debouncing ensures navigation occurs only after the user stops clicking.
    • Throttling limits navigation to once every specified interval.
  3. Optimization Choose debouncing for scenarios where a single navigation should occur after a pause. Use throttling when limiting the rate of navigation attempts is required.

Solution

Two implementation methods for debouncing and throttling are as follows, with example code provided:

// Debouncing: When a function is triggered multiple times within a certain period, debouncing ensures that the function is ultimately executed only once after a specified delay.
export function debounce(func: (event: ClickEvent) => void, delay?: number) {
  let timer: number;
  return (event: ClickEvent) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func(event);
    }, delay ? delay : 1000);
  };
}
// Throttling: Execute only once within the specified time frame.
export function throttle(func: (event: ClickEvent) => void, delay?: number) {
  let inThrottle: boolean;
  return (event: ClickEvent) => {
    if (!inThrottle) {
      func(event);
      inThrottle = true;
      setTimeout(() => inThrottle = false, delay ? delay : 1000);
    }
  };
}

@Entry
@Component
struct Index {
  @State num: number = 0
  @State num1: number = 0

  build() {
    Row() {
      Column() {
        Text(this.num.toString())
        Button('Throttle Example')
          .onClick(
            throttle(() => {
              this.num++
            }, 5000))
        Text(this.num1.toString())
        Button('Anti-shake example')
          .onClick(
            debounce(() => {
              this.num1++
            }, 5000))
      }
      .width('100%')
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Verification Result

input91.gif

Written by Emrecan Karakas

Top comments (0)