Greasy Fork is available in English.
全站通用型页内增强脚本
当前为
// ==UserScript==
// @name 当页开链
// @namespace http://greasyfork.icu/zh-CN/scripts/497533
// @version 3.2
// @description 全站通用型页内增强脚本
// @author none
// @match *://*/*
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @run-at document-body
// @connect *
// ==/UserScript==
(function() {
'use strict';
// 函数用于在当前标签页中打开链接
function openLinkInCurrentTab(url) {
window.location.href = url;
}
// 拦截所有点击事件
document.addEventListener('click', function(event) {
var target = event.target;
// 检查点击的元素以及其父元素是否是链接
while (target && target.tagName !== 'A') {
target = target.parentElement;
}
if (target && target.tagName === 'A') {
// 阻止默认行为,即在新标签页中打开链接
event.preventDefault();
// 获取链接的目标 URL
var url = target.href;
// 在当前标签页中打开链接
openLinkInCurrentTab(url);
}
});
// 协议安全名单(2025标准)
const SAFE_PROTOCOLS = new Set([
'http:', 'https:', 'ftp:',
'mailto:', 'tel:', 'sms:'
]);
// Shadow DOM处理器(支持5级嵌套)
const processShadowRoot = (root, depth = 0) => {
if (depth > 5) return;
root.querySelectorAll('a, form').forEach(processElement);
root.querySelectorAll('*').forEach(node => {
if (node.shadowRoot) {
processShadowRoot(node.shadowRoot, depth + 1);
}
});
};
// 增强元素处理逻辑
const processElement = (element) => {
// 协议过滤
try {
const href = element.href?.toLowerCase() || '';
const protocol = new URL(href, location.href).protocol;
if (!SAFE_PROTOCOLS.has(protocol)) return;
} catch(e) {
return;
}
// 多维度属性清理
['target', 'onclick', 'data-target'].forEach(attr => {
element.removeAttribute(attr);
});
// 表单提交劫持
if (element.matches('form') && !element.__patched) {
element.__patched = true;
const originalSubmit = element.submit;
element.submit = function() {
this.target = '_self';
originalSubmit.call(this);
};
}
};
// 全局基础策略
const applyBaseStrategy = () => {
if (!document.querySelector('base')) {
const base = document.createElement('base');
base.target = '_self';
document.head.prepend(base);
}
};
// 优化后的智能观察器(2025最新方案)
const initObserver = () => {
const processedElements = new WeakSet();
let pendingUpdates = new Set();
let updateScheduled = false;
const batchProcessor = () => {
const tempSet = new Set(pendingUpdates);
pendingUpdates.clear();
tempSet.forEach(node => {
if (node.nodeType === 1 && !processedElements.has(node)) {
// 处理主节点
processElement(node);
processedElements.add(node);
// 处理关联Shadow DOM
const processNestedShadow = (element, depth = 0) => {
if (depth > 5) return;
if (element.shadowRoot) {
element.shadowRoot.querySelectorAll('a').forEach(a => {
if (!processedElements.has(a)) {
processElement(a);
processedElements.add(a);
}
});
element.shadowRoot.querySelectorAll('*').forEach(child =>
processNestedShadow(child, depth + 1)
);
}
};
processNestedShadow(node);
}
});
updateScheduled = false;
};
const observer = new MutationObserver(mutations => {
mutations.forEach(({ addedNodes, attributeName, target }) => {
// 收集新增节点
addedNodes.forEach(node => {
if (node.nodeType === 1) {
pendingUpdates.add(node);
} else if (node.nodeType === 11) { // 处理文档片段
node.querySelectorAll('a').forEach(a =>
pendingUpdates.add(a)
);
}
});
// 响应属性变更
if (attributeName === 'target' && target.tagName === 'A') {
pendingUpdates.add(target);
}
});
// 智能调度处理
if (!updateScheduled && pendingUpdates.size) {
updateScheduled = true;
if (typeof requestIdleCallback === 'function') {
requestIdleCallback(batchProcessor, { timeout: 50 });
} else {
requestAnimationFrame(batchProcessor);
}
}
});
observer.observe(document, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['target', 'href']
});
};
// 路由劫持层(支持现代框架)
const hijackRouting = () => {
const routerApis = [
history.pushState,
history.replaceState,
unsafeWindow.router?.navigate
];
routerApis.forEach(fn => {
const original = fn;
fn = (...args) => {
const result = original.apply(this, args);
setTimeout(() => {
document.querySelectorAll('a').forEach(processElement);
}, requestAnimationFrame(() => 0));
return result;
};
});
};
// 核心初始化
const main = () => {
if (window.self !== window.top) return;
applyBaseStrategy();
hijackRouting();
// 初始处理
document.querySelectorAll('a, form').forEach(processElement);
processShadowRoot(document);
// 动态处理
initObserver();
// 全局事件拦截
document.addEventListener('click', e => {
const target = e.composedPath()[0];
if (target.matches('a')) processElement(target);
}, { capture: true, passive: true });
// 强化window.open处理
unsafeWindow.open = function(url, target, ...args) {
return window.open(url, '_self', ...args);
};
};
// 启动逻辑
if (document.readyState === 'complete') {
main();
} else {
document.addEventListener('DOMContentLoaded', main);
}
// 处理动态添加的链接,使用MutationObserver
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
$(mutation.addedNodes).find('a').attr('target', '_self');
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();