强制Github所有链接在新标签页打开
// ==UserScript==
// @name Github链接新标签页打开
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 强制Github所有链接在新标签页打开
// @author kang
// @license MIT
// @match *://github.com/*
// @icon https://img.icons8.com/?size=128&id=HBaR-srJq-eB&format=png
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// 增强型链接检测函数
const findValidLink = (element) => {
const MAX_DEPTH = 5; // 最大DOM层级搜索深度
let current = element;
let depth = 0;
while (current && depth++ < MAX_DEPTH) {
if (current.tagName === 'A' && current.href) {
// 排除伪链接和锚点
if (current.href.includes('javascript:') ||
current.href.startsWith('#')) return null;
return current;
}
current = current.parentElement;
}
return null;
};
// 主事件处理器
const handleClick = (event) => {
// 仅处理主按钮(左键)点击
if (event.button !== 0) return;
// 保留辅助键功能(Ctrl/Cmd/Shift)
if (event.ctrlKey || event.metaKey || event.shiftKey) return;
const link = findValidLink(event.target);
if (!link) return;
// 阻止默认行为并停止传播
event.preventDefault();
event.stopImmediatePropagation();
// 异步打开新标签页(兼容SPA)
setTimeout(() => {
window.open(link.href, '_blank', 'noopener noreferrer');
}, 50);
// 清除焦点状态
link.blur();
};
// 在捕获阶段优先注册监听器
document.addEventListener('click', handleClick, {
capture: true,
passive: false
});
// 处理动态内容的重置防护
let lastHref = location.href;
const observeChanges = () => {
if (location.href !== lastHref) {
lastHref = location.href;
document.addEventListener('click', handleClick, {
capture: true,
passive: false
});
}
requestAnimationFrame(observeChanges);
};
observeChanges();
})();