From bc3b55abe383ea4184035afa423e2b73d6823e24 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:26:00 +0900
Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20ArcoDesign/React=20?=
=?UTF-8?q?=E7=9A=84=20focusin/out=20=E4=BA=8B=E4=BB=B6=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/batchupdate/main.tsx | 3 +++
src/pages/confirm/main.tsx | 3 +++
src/pages/fix.ts | 48 ++++++++++++++++++++++++++++++++++
src/pages/import/main.tsx | 3 +++
src/pages/install/main.tsx | 3 +++
src/pages/options/main.tsx | 3 +++
src/pages/popup/main.tsx | 3 +++
7 files changed, 66 insertions(+)
create mode 100644 src/pages/fix.ts
diff --git a/src/pages/batchupdate/main.tsx b/src/pages/batchupdate/main.tsx
index f87ac8a8a..59d7c7647 100644
--- a/src/pages/batchupdate/main.tsx
+++ b/src/pages/batchupdate/main.tsx
@@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
import MainLayout from "../components/layout/MainLayout.tsx";
import LoggerCore from "@App/app/logger/core.ts";
import { message } from "../store/global.ts";
@@ -27,6 +28,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
diff --git a/src/pages/confirm/main.tsx b/src/pages/confirm/main.tsx
index 51985671b..14d20dde8 100644
--- a/src/pages/confirm/main.tsx
+++ b/src/pages/confirm/main.tsx
@@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
import MainLayout from "../components/layout/MainLayout.tsx";
import LoggerCore from "@App/app/logger/core.ts";
import { message } from "../store/global.ts";
@@ -26,6 +27,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
new file mode 100644
index 000000000..1720fbe00
--- /dev/null
+++ b/src/pages/fix.ts
@@ -0,0 +1,48 @@
+let actived = false;
+
+export const fixArcoIssues = () => {
+ if (actived) return;
+ actived = true;
+
+ const originalAddEventListener = HTMLElement.prototype.addEventListener;
+ type BindInfo = { thisArg: Element; listener: EventListener };
+
+ const stackedEvents = new Set();
+ const bindInfoMap = new WeakMap();
+ const executorFn = () => {
+ const events = [...stackedEvents];
+ stackedEvents.clear();
+ for (const ev of events) {
+ if (ev.defaultPrevented) continue;
+ const bi = bindInfoMap.get(ev);
+ if (!bi) continue;
+ bindInfoMap.delete(ev);
+ try {
+ bi.listener.call(bi.thisArg, ev);
+ } catch (err) {
+ console.error(err);
+ }
+ }
+ };
+
+ const addEventListenerHack = function (
+ this: Element,
+ type: K,
+ listener: EventListenerOrEventListenerObject,
+ options?: boolean | AddEventListenerOptions
+ ): void {
+ if ((type === "focusin" || type === "focusout") && typeof listener === "function") {
+ const handler = (event: Event) => {
+ stackedEvents.add(event);
+ bindInfoMap.set(event, { thisArg: this, listener });
+ requestAnimationFrame(executorFn);
+ };
+ return originalAddEventListener.call(this, type, handler, options);
+ }
+ return originalAddEventListener.call(this, type, listener, options);
+ };
+ document.body.addEventListener = addEventListenerHack;
+
+ const root = document.querySelector("div#root");
+ if (root) root.addEventListener = addEventListenerHack;
+};
diff --git a/src/pages/import/main.tsx b/src/pages/import/main.tsx
index fe51ddedd..2802dd082 100644
--- a/src/pages/import/main.tsx
+++ b/src/pages/import/main.tsx
@@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
import MainLayout from "../components/layout/MainLayout.tsx";
import LoggerCore from "@App/app/logger/core.ts";
import { message } from "../store/global.ts";
@@ -26,6 +27,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
diff --git a/src/pages/install/main.tsx b/src/pages/install/main.tsx
index 7f87023e2..95f4faf2f 100644
--- a/src/pages/install/main.tsx
+++ b/src/pages/install/main.tsx
@@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
import MainLayout from "../components/layout/MainLayout.tsx";
import LoggerCore from "@App/app/logger/core.ts";
import { message } from "../store/global.ts";
@@ -38,6 +39,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
diff --git a/src/pages/options/main.tsx b/src/pages/options/main.tsx
index 096203c58..bbd927b77 100644
--- a/src/pages/options/main.tsx
+++ b/src/pages/options/main.tsx
@@ -3,6 +3,7 @@ import ReactDOM from "react-dom/client";
import MainLayout from "../components/layout/MainLayout.tsx";
import Sider from "../components/layout/Sider.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
import "@arco-design/web-react/dist/css/arco.css";
import "@App/locales/locales";
import "@App/index.css";
@@ -33,6 +34,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
diff --git a/src/pages/popup/main.tsx b/src/pages/popup/main.tsx
index 05b3e94c1..d0b21556c 100644
--- a/src/pages/popup/main.tsx
+++ b/src/pages/popup/main.tsx
@@ -10,6 +10,7 @@ import "@App/index.css";
import "./index.css";
import PopupLayout from "../components/layout/PopupLayout.tsx";
import { AppProvider } from "../store/AppContext.tsx";
+import { fixArcoIssues } from "@App/pages/fix.ts";
// 初始化日志组件
const loggerCore = new LoggerCore({
@@ -27,6 +28,8 @@ const Root = (
);
+fixArcoIssues();
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
process.env.NODE_ENV === "development" ? {Root} : Root
);
From 53d561d12a8beeceea53154a628e7254627757c9 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:32:37 +0900
Subject: [PATCH 2/9] Update fix.ts
---
src/pages/fix.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 1720fbe00..c27530616 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -10,6 +10,7 @@ export const fixArcoIssues = () => {
const stackedEvents = new Set();
const bindInfoMap = new WeakMap();
const executorFn = () => {
+ if (!stackedEvents.size) return;
const events = [...stackedEvents];
stackedEvents.clear();
for (const ev of events) {
From 0a4b69a0b0fb553d0483c9b5d032a174cf0b515d Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 13:44:43 +0900
Subject: [PATCH 3/9] Update src/pages/fix.ts
Co-authored-by: wangyizhi
---
src/pages/fix.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index c27530616..9afbfb9a3 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -1,3 +1,5 @@
+// 修复arco中的事件问题 https://github.com/scriptscat/scriptcat/pull/1224/
+
let actived = false;
export const fixArcoIssues = () => {
From 025411a63e09b89f5fd6b90eb5e268958b7d886a Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 13:52:46 +0900
Subject: [PATCH 4/9] fix code order
---
src/pages/fix.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 9afbfb9a3..63b62a0af 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -16,10 +16,10 @@ export const fixArcoIssues = () => {
const events = [...stackedEvents];
stackedEvents.clear();
for (const ev of events) {
- if (ev.defaultPrevented) continue;
const bi = bindInfoMap.get(ev);
if (!bi) continue;
bindInfoMap.delete(ev);
+ if (ev.defaultPrevented) continue;
try {
bi.listener.call(bi.thisArg, ev);
} catch (err) {
From 42a6ca355b744961025be97d9804a7f5f19b5471 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 17:32:32 +0900
Subject: [PATCH 5/9] =?UTF-8?q?=E6=8A=8A=E4=BA=8B=E4=BB=B6=E8=A7=A6?=
=?UTF-8?q?=E5=8F=91=E6=8E=92=E7=A8=8B=E5=9C=A8=E4=B8=8B=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=20marcoTask=20=E8=80=8C=E9=9D=9E=20rAF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/fix.ts | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 63b62a0af..612877d57 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -28,6 +28,12 @@ export const fixArcoIssues = () => {
}
};
+ self.addEventListener("message", (ev) => {
+ if (typeof ev.data === "object" && ev.data?.browserNextTick === "addEventListenerHack") {
+ executorFn();
+ }
+ });
+
const addEventListenerHack = function (
this: Element,
type: K,
@@ -35,10 +41,10 @@ export const fixArcoIssues = () => {
options?: boolean | AddEventListenerOptions
): void {
if ((type === "focusin" || type === "focusout") && typeof listener === "function") {
- const handler = (event: Event) => {
- stackedEvents.add(event);
- bindInfoMap.set(event, { thisArg: this, listener });
- requestAnimationFrame(executorFn);
+ const handler = (ev: Event) => {
+ stackedEvents.add(ev);
+ bindInfoMap.set(ev, { thisArg: this, listener });
+ self.postMessage({ browserNextTick: "addEventListenerHack" });
};
return originalAddEventListener.call(this, type, handler, options);
}
From 76958f47ecdaf459b86c78f16b6c9877a030ef24 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 17:41:36 +0900
Subject: [PATCH 6/9] =?UTF-8?q?=E5=8A=A0=E5=85=A5=20options=20=E5=88=A4?=
=?UTF-8?q?=E6=96=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/fix.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 612877d57..38bf0549f 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -40,7 +40,11 @@ export const fixArcoIssues = () => {
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions
): void {
- if ((type === "focusin" || type === "focusout") && typeof listener === "function") {
+ if (
+ (type === "focusin" || type === "focusout") &&
+ typeof listener === "function" &&
+ typeof (options ?? false) === "boolean" // accept capture event or bubble event but exclude the advanced options like "once"
+ ) {
const handler = (ev: Event) => {
stackedEvents.add(ev);
bindInfoMap.set(ev, { thisArg: this, listener });
From d915d80f59ee363a79b9e7a78cf75433b643a250 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 18:05:06 +0900
Subject: [PATCH 7/9] =?UTF-8?q?=E5=8A=A0=E5=85=A5AI=E5=BB=BA=E8=AE=AE?=
=?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/fix.ts | 50 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 40 insertions(+), 10 deletions(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 38bf0549f..74b82c8a3 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -1,61 +1,91 @@
-// 修复arco中的事件问题 https://github.com/scriptscat/scriptcat/pull/1224/
+// 修复 Arco Design 在 React 17+ 环境下 focusin / focusout 事件重复触发导致的 UI 卡顿问题
+// 参考 PR:https://github.com/scriptscat/scriptcat/pull/1224
+// 核心思路:将 focusin/focusout 的事件监听器执行延迟到下一个 macrotask,避免在同一渲染帧内被 Arco 多次触发
-let actived = false;
+let actived = false; // 防止多次调用 fixArcoIssues 导致重复 patch
export const fixArcoIssues = () => {
- if (actived) return;
+ if (actived) return; // 已修复过则直接返回
actived = true;
+ // 保存原生的 addEventListener 方法
const originalAddEventListener = HTMLElement.prototype.addEventListener;
- type BindInfo = { thisArg: Element; listener: EventListener };
+ // 用来暂存需要延迟执行的事件物件
const stackedEvents = new Set();
- const bindInfoMap = new WeakMap();
+
+ // 记录每个事件对应的 thisArg 和 listener(因为我们会包一层 handler)
+ const bindInfoMap = new WeakMap();
+
+ // 真正执行被延迟的事件回调
const executorFn = () => {
if (!stackedEvents.size) return;
+
+ // 复制一份后清空,避免在执行期间又有新事件进来
const events = [...stackedEvents];
stackedEvents.clear();
+
for (const ev of events) {
const bi = bindInfoMap.get(ev);
if (!bi) continue;
- bindInfoMap.delete(ev);
+
+ bindInfoMap.delete(ev); // 用完即清理,减少 WeakMap 引用
+
+ // 如果事件已被 preventDefault,则不再执行原回调(保持标准行为)
if (ev.defaultPrevented) continue;
+
try {
+ // 使用原来的 this 和 listener 执行
bi.listener.call(bi.thisArg, ev);
} catch (err) {
- console.error(err);
+ console.error("Failed to execute delayed callback.", err);
}
}
};
+ // 使用 postMessage + message 事件来实现 macrotask(比 setTimeout(0) 更可靠且开销较小)
self.addEventListener("message", (ev) => {
if (typeof ev.data === "object" && ev.data?.browserNextTick === "addEventListenerHack") {
executorFn();
}
});
+ // 自订的 addEventListener 拦截器,只针对 focusin/focusout 且 options 为简单 boolean 时生效
const addEventListenerHack = function (
this: Element,
type: K,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions
): void {
+ // 只拦截 focusin / focusout,且 listener 是函数,且 options 是简单的 capture/bubble 设定
+ // (排除 once、passive 等进阶选项,避免破坏其他使用方式)
if (
(type === "focusin" || type === "focusout") &&
typeof listener === "function" &&
- typeof (options ?? false) === "boolean" // accept capture event or bubble event but exclude the advanced options like "once"
+ typeof (options ?? false) === "boolean" // 只接受 boolean 或 undefined 的 options
) {
+ // 包装一层 handler,收集事件并推迟执行
const handler = (ev: Event) => {
stackedEvents.add(ev);
bindInfoMap.set(ev, { thisArg: this, listener });
- self.postMessage({ browserNextTick: "addEventListenerHack" });
+ // 发送 macrotask 讯号,让 executor 在下一个事件循环执行
+ self.postMessage({ browserNextTick: "addEventListenerHack" }, "*");
};
+
+ // 用包装后的 handler 注册真正的事件
return originalAddEventListener.call(this, type, handler, options);
}
+
+ // 其他事件走原生方法,不做干预
return originalAddEventListener.call(this, type, listener, options);
};
+
+ // 针对 body 打补丁(Arco 大量事件绑在 document 或 body 上)
document.body.addEventListener = addEventListenerHack;
+ // 也针对 React 根节点 #root 打补丁(部分组件可能绑在根元素)
const root = document.querySelector("div#root");
- if (root) root.addEventListener = addEventListenerHack;
+ if (root) {
+ root.addEventListener = addEventListenerHack;
+ }
};
From f787cfd4e67561f9e94a840d198ac71ca8abe830 Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 18:12:43 +0900
Subject: [PATCH 8/9] browserNextTick -> processNextTick
---
src/pages/fix.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index 74b82c8a3..f3424a43d 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -45,7 +45,7 @@ export const fixArcoIssues = () => {
// 使用 postMessage + message 事件来实现 macrotask(比 setTimeout(0) 更可靠且开销较小)
self.addEventListener("message", (ev) => {
- if (typeof ev.data === "object" && ev.data?.browserNextTick === "addEventListenerHack") {
+ if (typeof ev.data === "object" && ev.data?.processNextTick === "addEventListenerHack") {
executorFn();
}
});
@@ -69,7 +69,7 @@ export const fixArcoIssues = () => {
stackedEvents.add(ev);
bindInfoMap.set(ev, { thisArg: this, listener });
// 发送 macrotask 讯号,让 executor 在下一个事件循环执行
- self.postMessage({ browserNextTick: "addEventListenerHack" }, "*");
+ self.postMessage({ processNextTick: "addEventListenerHack" }, "*");
};
// 用包装后的 handler 注册真正的事件
From e61ed4ff56becd9d3b2bd6a03b944daed4b9454f Mon Sep 17 00:00:00 2001
From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com>
Date: Mon, 9 Feb 2026 18:41:19 +0900
Subject: [PATCH 9/9] =?UTF-8?q?=E5=8A=A0=E5=85=A5=20removeEventListenerHac?=
=?UTF-8?q?k=EF=BC=8C=20=E4=BF=AE=E8=AE=A2=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/fix.ts | 43 +++++++++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/pages/fix.ts b/src/pages/fix.ts
index f3424a43d..05debc2f2 100644
--- a/src/pages/fix.ts
+++ b/src/pages/fix.ts
@@ -8,10 +8,11 @@ export const fixArcoIssues = () => {
if (actived) return; // 已修复过则直接返回
actived = true;
- // 保存原生的 addEventListener 方法
+ // 保存原生的 addEventListener / removeEventListener 方法
const originalAddEventListener = HTMLElement.prototype.addEventListener;
+ const originalRemoveEventListener = HTMLElement.prototype.removeEventListener;
- // 用来暂存需要延迟执行的事件物件
+ // 用来暂存需要延迟执行的事件对象(同一 tick 内的事件会被合并)
const stackedEvents = new Set();
// 记录每个事件对应的 thisArg 和 listener(因为我们会包一层 handler)
@@ -29,28 +30,37 @@ export const fixArcoIssues = () => {
const bi = bindInfoMap.get(ev);
if (!bi) continue;
- bindInfoMap.delete(ev); // 用完即清理,减少 WeakMap 引用
+ // 使用完成后立即清理,减少 WeakMap 的引用存活时间
+ bindInfoMap.delete(ev);
- // 如果事件已被 preventDefault,则不再执行原回调(保持标准行为)
+ // 如果事件已被 preventDefault,则不再执行原回调
+ // 保持浏览器原生事件行为一致
if (ev.defaultPrevented) continue;
try {
// 使用原来的 this 和 listener 执行
bi.listener.call(bi.thisArg, ev);
} catch (err) {
+ // 捕获异常,避免影响后续事件执行
console.error("Failed to execute delayed callback.", err);
}
}
};
- // 使用 postMessage + message 事件来实现 macrotask(比 setTimeout(0) 更可靠且开销较小)
+ // 使用 postMessage + message 事件来模拟 macrotask
+ // 相比 setTimeout(0),更稳定且调度开销更小
self.addEventListener("message", (ev) => {
if (typeof ev.data === "object" && ev.data?.processNextTick === "addEventListenerHack") {
executorFn();
}
});
- // 自订的 addEventListener 拦截器,只针对 focusin/focusout 且 options 为简单 boolean 时生效
+ // 记录原始 listener 与包装后 handler 的映射关系
+ // 以便 removeEventListener 时能正确移除
+ const handlerMap = new WeakMap();
+
+ // 自定义的 addEventListener
+ // 只针对 focusin / focusout 且 options 为简单 boolean 的情况生效
const addEventListenerHack = function (
this: Element,
type: K,
@@ -72,20 +82,37 @@ export const fixArcoIssues = () => {
self.postMessage({ processNextTick: "addEventListenerHack" }, "*");
};
- // 用包装后的 handler 注册真正的事件
+ // 保存原 listener 与包装 handler 的对应关系
+ handlerMap.set(listener, handler);
+
+ // 实际注册的是包装后的 handler
return originalAddEventListener.call(this, type, handler, options);
}
- // 其他事件走原生方法,不做干预
+ // 其他事件保持原生行为,不做任何干预
return originalAddEventListener.call(this, type, listener, options);
};
+ // 自定义的 removeEventListener
+ // 如果 listener 曾被包装过,这里需要移除对应的 handler
+ const removeEventListenerHack = function (
+ this: Element,
+ type: K,
+ listener: EventListenerOrEventListenerObject,
+ options?: boolean | AddEventListenerOptions
+ ): void {
+ const handler = typeof listener === "function" && handlerMap.get(listener);
+ return originalRemoveEventListener.call(this, type, handler || listener, options);
+ };
+
// 针对 body 打补丁(Arco 大量事件绑在 document 或 body 上)
document.body.addEventListener = addEventListenerHack;
+ document.body.removeEventListener = removeEventListenerHack;
// 也针对 React 根节点 #root 打补丁(部分组件可能绑在根元素)
const root = document.querySelector("div#root");
if (root) {
root.addEventListener = addEventListenerHack;
+ root.removeEventListener = removeEventListenerHack;
}
};