← 中文资源

简体中文版本

被动事件监听器

被动监听器向浏览器承诺 touch 与 wheel 处理器绝不调用 preventDefault,浏览器因此无需等待 JavaScript 执行完即可立刻开始滚动。

阅读英文原文

概念定义

浏览器无法预知滚动处理器会不会取消滚动,历史上只能等处理器跑完再滚动。被动注册就是承诺“不会取消”:滚动与脚本并行启动,即便主线程繁忙,滚动仍由合成器驱动,不再卡顿。

工作机制

addEventListener 传 passive: true 即注册承诺;此类处理器内调用 preventDefault 会被忽略并告警。现代浏览器中 window 与 document 上的 touch 与 wheel 根监听默认就是被动,主动退出被动反而要付平滑性代价。

使用场景

一切观察式滚动或触摸处理器:分析打点、视差触发、无限滚动探测。非被动只留给真正的拦截者:自定义手势、下拉刷新、必须吞掉纵向滚动的横向轮播。

常见误区

被动并不让处理器本身变快:漫长的滚动处理器照样拖延布局与定时器等其他主线程工作。忘记退出被动的手势代码会静默失效,产出半残交互。旧引擎把所有监听器视为非被动,默认值差异需要特性检测。

代码示例

public class StringBuilderManipulation {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder(64);

        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        System.out.println("Built: " + sb);

        sb.insert(5, " Java");
        System.out.println("After insert: " + sb);

        sb.delete(5, 10);
        System.out.println("After delete: " + sb);

        sb.replace(0, 5, "Hi");
        System.out.println("After replace: " + sb);

        sb.reverse();
        System.out.println("Reversed: " + sb);

        String csv = String.join(", ",
            "Apple", "Banana", "Cherry", "Date");
        System.out.println("CSV: " + csv);

        String formatted = String.format(
            "Name: %s, Age: %d, Score: %.2f",
            "Alice", 30, 95.5
        );
        System.out.println(formatted);

        String stripped = "  padded  ".strip();
        System.out.println("Stripped: '" + stripped + "'");
    }
}