domToolkit

DOM 工具库:Shadow DOM 穿透、异步元素查找、事件委托、样式注入

Αυτός ο κώδικας δεν πρέπει να εγκατασταθεί άμεσα. Είναι μια βιβλιοθήκη για άλλους κώδικες που περιλαμβάνεται μέσω της οδηγίας meta // @require https://update.greasyfork.org/scripts/559176/1715549/domToolkit.js

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

Δημιουργός
urzeye
Έκδοση
1.1.0
Δημιουργήθηκε την
17/12/2025
Ενημερώθηκε την
17/12/2025
Μέγεθος
30 KB
Άδεια
MIT

lib - 通用工具库

供油猴脚本通过 @require 引入的通用工具集。

目录

工具 描述
backgroundKeepAlive.user.js 后台保活工具集
domToolkit.user.js DOM 操作工具库

domToolkit.user.js

专为 Tampermonkey 脚本设计的高性能 DOM 工具库,解决以下痛点:

  • Shadow DOM 穿透查找 - 现代 Web 组件的难题
  • 异步等待元素出现 - 动态渲染页面必备
  • 持续监听新元素 - SPA 应用场景
  • 事件委托 - 减少事件绑定开销
  • 样式注入 - 支持 Shadow DOM

引入方式

// ==UserScript==
// @require https://update.greasyfork.org/scripts/XXXXX/xxx/domToolkit.js
// ==/UserScript==

API: query() - 同步查询

支持 Shadow DOM 穿透的同步元素查找。

// 查找单个元素
const btn = DOMToolkit.query("button.submit");

// 查找所有匹配元素
const items = DOMToolkit.query(".item", {all: true});

// 在 Shadow DOM 中查找(默认启用)
const input = DOMToolkit.query("input.main", {shadow: true});

// 多选择器支持(返回第一个匹配)
const el = DOMToolkit.query(["button.submit", 'input[type="submit"]']);

// 使用自定义过滤函数
const textarea = DOMToolkit.query("[contenteditable]", {
    shadow: true,
    filter: (el) => el.offsetParent !== null && !el.closest("#my-panel"),
});

参数: | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | parent | Node | document | 查询起点 | | all | boolean | false | 是否返回所有匹配 | | shadow | boolean | true | 是否穿透 Shadow DOM | | maxDepth | number | 15 | 最大递归深度 | | useCache | boolean | true | 是否使用缓存(有 filter 时自动禁用) | | filter | function | null | 自定义过滤函数 (el) => boolean |


API: get() - 异步获取

等待元素出现,支持超时控制。

// 等待元素出现(默认 5 秒超时)
const modal = await DOMToolkit.get(".modal");

// 自定义超时时间
const btn = await DOMToolkit.get("button.action", {timeout: 10000});

// 无限等待
const el = await DOMToolkit.get(".dynamic", {timeout: 0});

API: each() - 持续监听

处理现在和未来所有匹配的元素。

// 处理所有(现有和未来的)按钮
const stop = DOMToolkit.each("button.action", (btn, isNew) => {
    btn.style.color = "blue";
    if (isNew) console.log("New button added");
});

// 稍后停止监听
stop();

// 返回 false 可提前停止
DOMToolkit.each(".item", (el) => {
    if (el.id === "target") {
        console.log("Found target");
        return false; // 停止监听
    }
});

API: on() - 事件委托

事件委托,自动处理 Shadow DOM 中的事件。

// 委托点击事件
const remove = DOMToolkit.on("click", ".item", (event, target) => {
    console.log("Item clicked:", target);
});

// 稍后移除
remove();

// 捕获阶段
DOMToolkit.on("click", ".btn", callback, {capture: true});

API: create() / createFromHTML() - 元素创建

// 创建元素
const btn = DOMToolkit.create(
    "button",
    {
        className: "primary",
        id: "submit",
        style: {color: "white", background: "blue"},
        onClick: () => console.log("clicked"),
    },
    "Submit"
);

// 从 HTML 字符串创建
const div = DOMToolkit.createFromHTML('<div class="card"><p>Hello</p></div>');

// 获取 ID 映射
const {root, title, content} = DOMToolkit.createFromHTML(
    `
    <div id="container">
        <h1 id="title">Title</h1>
        <p id="content">Content</p>
    </div>
`,
    {mapIds: true}
);

API: css() / cssToShadow() / cssToAllShadows() - 样式注入

// 全局样式
DOMToolkit.css(".highlight { background: yellow; }", "my-styles");

// 向单个 Shadow DOM 注入
DOMToolkit.cssToShadow(shadowRoot, css, "shadow-styles");

// 向所有 Shadow DOM 注入
DOMToolkit.cssToAllShadows(css, "all-shadow-styles");

// 过滤特定 Shadow Host
DOMToolkit.cssToAllShadows(css, "id", {
    filter: (host) => !host.closest(".sidebar"),
});

API: walkShadowRoots() - Shadow DOM 遍历

DOMToolkit.walkShadowRoots((shadowRoot, host) => {
    console.log("Found shadow root on:", host.tagName);
});

API: findScrollContainer() - 查找滚动容器

// 使用默认逻辑(Shadow DOM 优先,然后 documentElement/body)
const scroller = DOMToolkit.findScrollContainer();

// 提供站点特定的选择器(优先匹配)
const scroller = DOMToolkit.findScrollContainer({
    selectors: [".chat-mode-scroller", ".conversation-container", "main"],
});

其他 API

DOMToolkit.clear(element); // 清空元素内容
DOMToolkit.clearCache(); // 清除缓存
DOMToolkit.configCache({enabled: false}); // 禁用缓存
DOMToolkit.destroy(); // 销毁实例

backgroundKeepAlive.user.js

解决浏览器后台标签页节流问题的通用工具集,包含三大模块。

引入方式

// ==UserScript==
// @require https://update.greasyfork.org/scripts/559089/1714656/background-keep-alive.js
// ==/UserScript==

模块 1: BackgroundTimer

基于 Web Worker 的保活定时器,绑定后台环境下不被节流。

const timer = new BackgroundTimer(() => {
    console.log("心跳:", new Date().toTimeString());
}, 1000);

timer.start(); // 启动
timer.stop(); // 停止
timer.setInterval(2000); // 动态调整间隔
timer.isRunning(); // 获取状态
timer.destroy(); // 销毁实例

模块 2: AudioKeepAlive

使用静音音频对抗 Chrome 5 分钟强力休眠。

⚠️ 需要用户交互后才能启动(浏览器自动播放策略限制)

const audio = new AudioKeepAlive();

// 需要在用户交互后启动
document.addEventListener("click", () => audio.start(), {once: true});

audio.stop(); // 停止
audio.isActive(); // 获取状态
audio.destroy(); // 销毁实例

模块 3: NetworkMonitor

Hook Fetch 和 XHR 监控任务完成状态,使用防抖 + 活跃计数器算法。

const monitor = new NetworkMonitor({
    // 监控的 URL 模式(包含匹配)
    // 注意:避免使用通用 RPC 方法如 batchexecute,会产生误判
    urlPatterns: ["BardFrontendService", "StreamGenerate"],

    // 静默判定时间(毫秒)
    silenceThreshold: 3000,

    // 任务完成回调
    onComplete: (ctx) => {
        console.log("任务完成", ctx);
        // ctx = { activeCount, lastUrl, timestamp }
    },

    // 任务开始回调(可选)
    onStart: (ctx) => {
        console.log("任务开始", ctx);
    },

    // DOM 二次验证(可选,自定义)
    domValidation: (ctx) => {
        // 返回 true 表示验证通过,触发 onComplete
        // 返回 false 表示还需等待
        return !document.querySelector(".stop-button");
    },
});

monitor.start(); // 开始监控
monitor.stop(); // 停止监控
monitor.isIdle(); // 是否空闲
monitor.getActiveCount(); // 活跃请求数
monitor.destroy(); // 销毁实例

算法说明

  1. 记录当前活跃请求数
  2. 每次请求开始/结束都重置静默计时器
  3. 活跃数为 0 + 静默期结束 + DOM 验证通过 → 触发 onComplete