DEV Community

HarmonyOS
HarmonyOS

Posted on

Listening to Scroll in ArkUI Web: Global Scroll & Bottom Detection with onScroll - onOverScroll

Read the original article:Listening to Scroll in ArkUI Web: Global Scroll & Bottom Detection with onScroll - onOverScroll

Listening to Scroll in ArkUI Web: Global Scroll & Bottom Detection with onScroll - onOverScroll

Requirement Description

Provide a way to detect the scroll direction and position for a page rendered inside the ArkUI Web component:

  • Detect up/down scrolling.
  • Detect when the page has reached the top or bottom.

Background Knowledge

  • Web.onScroll — notifies the global page scroll position. It won’t fire for local (element-level) scrolls inside the page.

Tip: To confirm global scrolling, compare window.pageYOffset / window.pageXOffset before vs. after scroll.

  • Scroll.onWillScroll — ArkUI Scroll’s pre-scroll callback (for ArkUI scroll containers, not Web).

Docs: https://developer.huawei.com/consumer/en/doc/harmonyos-references/ts-container-scroll#onwillscroll12

  • Web.onOverScroll — detects overscroll at top/bottom (or left/right), useful to infer “reached end.”

Implementation Steps

  1. Enable scroll events on the Web component and register onScroll for global page scroll detection.
  2. Keep a previous offset to infer direction (up vs. down) by comparing event.yOffset.
  3. Use onOverScroll to determine top (yOffset < 0) or bottom (yOffset > 0) overscroll states.
  4. (Optional) If your H5 page uses local scrolling containers (not global), consider adding a small JS bridge or adjusting the H5 layout to permit global scrolling, since Web.onScroll won’t receive local scroll changes.

Code Snippet / Configuration

Detect global scroll direction with Web.onScroll:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebPage {
  controller: webview.WebviewController = new webview.WebviewController();
  // Track last global vertical offset
  private lastYOffset: number = 0;

  build() {
    Column() {
      Web({
        src: 'https://www.example.com',
        controller: this.controller
      })
        .javaScriptAccess(true)
        .domStorageAccess(true)
        .verticalScrollBarAccess(true)
        .onScroll((event) => {
          // event.yOffset is the page's GLOBAL vertical offset
          if (event.yOffset > this.lastYOffset) {
            console.info('Scrolling down');
          } else if (event.yOffset < this.lastYOffset) {
            console.info('Scrolling up');
          }
          this.lastYOffset = event.yOffset;
        })
        // Detect overscroll → infer top/bottom
        .onOverScroll((event) => {
          if (event.yOffset < 0) {
            console.info('Reached top');
          } else if (event.yOffset > 0) {
            console.info('Reached bottom');
          }
        });
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: Web.onScroll only reports global scroll. If the site uses an inner scrollable div (local scroll), onScroll won’t fire. For such cases, adjust the page to scroll the window (global) or implement an in-page JS listener posting messages back to ArkUI via the web controller/JS bridge.

Test Results

  • Up/down direction is correctly logged by comparing successive yOffsets.
  • onOverScroll reliably reports overscroll at top (yOffset < 0) and bottom (yOffset > 0).

Limitations or Considerations

  • Local scroll containers inside H5 won’t trigger Web.onScroll. Consider global scrolling or a JS bridge.
  • Cross-site pages may restrict injected JS; prefer cooperation with the H5 team when possible.
  • Wearables: keep logs and side effects light; avoid expensive work in scroll callbacks. Ensure high-contrast UI and minimal layout jank.

Related Documents or Links

Written by Bunyamin Eymen Alagoz

Top comments (0)