
本文介绍一种轻量、无需修改源码的浏览器端方案:通过用户脚本(userscript)自动识别页面中出现的“rq1”“rq2”“rq3”等关键词,并将其动态转换为指向对应介绍段落的内部锚点链接,提升长文档阅读效率。
本文介绍一种轻量、无需修改源码的浏览器端方案:通过用户脚本(userscript)自动识别页面中出现的“rq1”“rq2”“rq3”等关键词,并将其动态转换为指向对应介绍段落的内部锚点链接,提升长文档阅读效率。
在阅读技术论文或结构化报告(如 arXiv 页面)时,常遇到类似「RQ1」「RQ2」这类研究问题缩写反复出现于不同章节,但原文未提供跳转锚点。手动滚动回引言定位既低效又打断思路。本文提供一个纯前端、零依赖、即装即用的解决方案——利用 JavaScript 动态注入锚点链接。
✅ 核心原理
-
定位目标锚点:先找到引言中
RQ1、RQ2、RQ3对应的 DOM 元素(例如<h3 id="rq1-intro">RQ1: …</h3>),为其添加唯一id(若尚无); -
扫描全文关键词:遍历所有文本节点,匹配正则
/RQ\d+/i(支持大小写及空格变体); -
包裹可点击链接:将每个匹配词替换为
<a href="#rq1">RQ1</a>等带href的<a></a>标签; -
平滑滚动增强体验:配合 CSS
scroll-behavior: smooth实现流畅跳转。
?️ 实现示例(Userscript 版)
安装 Tampermonkey 后,新建脚本并粘贴以下代码:
// ==UserScript==
// @name Auto-Link RQ Anchors
// @namespace https://github.com/user
// @version 1.0
// @description Auto-convert RQ1/RQ2/RQ3 to internal anchor links
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Step 1: Ensure anchor IDs exist in intro section
const intro = document.querySelector('section#introduction, h1:first-of-type ~ *, .abstract, [class*="intro"]') || document.body;
const rqHeaders = intro.querySelectorAll('strong, b, h2, h3, h4');
const idMap = {};
['RQ1', 'RQ2', 'RQ3'].forEach((rq, i) => {
const el = Array.from(rqHeaders).find(h =>
h.textContent?.trim().toUpperCase().includes(rq)
);
if (el && !el.id) {
const id = `rq${i+1}-anchor`;
el.id = id;
idMap[rq.toLowerCase()] = `#${id}`;
}
});
// Step 2: Wrap all RQX occurrences in <a> tags
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
{ acceptNode: node =>
/rq\d+/i.test(node.textContent) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
}
);
const regex = /(rq\d+)/gi;
while (walker.nextNode()) {
const text = walker.currentNode;
const parent = text.parentNode;
const content = text.textContent;
if (!content.trim()) continue;
const replaced = content.replace(regex, (match) => {
const lower = match.toLowerCase();
const href = idMap[lower] || '#';
return `</a><a href="%24%7Bhref%7D" style="color:#1a0dab;text-decoration:underline;cursor:pointer;">${match}</a>`;
});
if (replaced !== content) {
const span = document.createElement('span');
span.innerHTML = replaced;
parent.replaceChild(span, text);
}
}
// Optional: Enable smooth scrolling globally
document.documentElement.style.scrollBehavior = 'smooth';
})();
⚠️ 注意事项
-
ID 唯一性优先:脚本会尝试在引言中查找
RQ1等标题元素并自动赋 ID;若页面已有同名 ID,请手动检查避免冲突; -
匹配灵活性:正则
/rq\d+/i可覆盖Rq1、rq2、RQ3等写法,如需扩展(如Research Question 1),可调整正则; - 性能友好:仅遍历文本节点,对大型页面也无明显卡顿;
-
arXiv 特别提示:arXiv HTML 版本(如
2403.17336v1)通常无原生锚点,本脚本可完美补全——您提供的链接中RQ1描述位于2.1 Definition and Principle...小节,脚本会将其设为#rq1-anchor并链接所有RQ1引用; - 安全无侵入:所有操作在内存中完成,不发送数据、不修改服务器内容,完全本地执行。
? 进阶建议:若希望长期复用,可将此逻辑封装为浏览器扩展,或结合
MutationObserver监听动态加载内容(如 SPA 页面)。但对于静态论文页,上述脚本已足够可靠、简洁、高效。
从此,点击任意 RQ2,瞬间回到引言定义处——让阅读回归专注,而非寻址。










