// ==UserScript==
// @name 左键点击链接在新标签页打开
// @name:en Open Links in New Tab with Left Click
// @namespace https://greasyfork.org/users/your-username // 建议替换为你的 GreasyFork 用户名或自定义命名空间
// @version 1.0
// @description 强制所有鼠标左键点击的普通链接都在新的浏览器标签页中打开。
// @description:en Forces all regular links clicked with the left mouse button to open in a new browser tab.
// @author AI Assistant
// @match *://*/*
// @grant GM_openInTab
// @grant window.open
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
document.addEventListener('click', function(event) {
// 1. 检查是否为鼠标左键点击 (event.button === 0)
// 并且没有同时按下 Ctrl, Meta (Cmd), Shift, Alt 等修饰键
// (因为这些组合键通常已有浏览器默认的新标签页打开行为)
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
return;
}
// 2. 查找被点击的 元素
// 用户可能点击的是 标签内部的文字、图片等子元素
let targetElement = event.target;
let anchorElement = null;
// 向上遍历DOM树,最多检查5层 (通常足够了)
for (let i = 0; i < 5 && targetElement && targetElement !== document.body; i++) {
if (targetElement.tagName === 'A') {
anchorElement = targetElement;
break;
}
targetElement = targetElement.parentElement;
}
// 3. 如果找到了 元素
if (anchorElement) {
const href = anchorElement.href; // 使用 .href 获取完整的、经过解析的绝对URL
const rawHref = anchorElement.getAttribute('href'); // 获取原始 href 属性值
// 4. 过滤无效或特殊链接
if (!href || href === '#' || (rawHref && rawHref.startsWith('#')) || href.startsWith('javascript:')) {
// - !href: 没有 href 属性
// - href === '#': 无效的空锚点 (现代浏览器中 .href 对 '#' 会是当前页面URL + '#')
// - rawHref.startsWith('#'): 明确的页面内锚点链接
// - href.startsWith('javascript:'): JavaScript 伪协议
return;
}
// 5. 忽略带有 download 属性的链接 (这类链接点击后浏览器会开始下载)
if (anchorElement.hasAttribute('download')) {
return;
}
// 6. (可选) 忽略那些已经明确指定 target="_blank" (或其他非 _self 的 target) 的链接
// 如果你希望严格覆盖所有行为,可以注释掉下面这个 if 块。
// 但通常尊重页面自身的 target 设置会是更好的体验。
/*
if (anchorElement.target && anchorElement.target.toLowerCase() !== '_self') {
return;
}
*/
// 7. 阻止链接的默认点击行为 (例如,在当前页面跳转)
event.preventDefault();
event.stopPropagation(); // 同时阻止事件冒泡,避免其他监听器干扰或重复处理
// 8. 在新标签页打开链接
// 优先使用 GM_openInTab (油猴脚本提供的API,通常有更好的集成和权限)
// 如果 GM_openInTab 不可用,则回退到标准的 window.open
if (typeof GM_openInTab === 'function') {
GM_openInTab(href, { active: true, insert: true });
// active: true => 新打开的标签页会成为当前焦点
// insert: true => (Tampermonkey 特有) 新标签页会插入到当前标签页旁边
} else if (typeof window.open === 'function') {
window.open(href, '_blank');
} else {
// 理论上不太可能两者都不可用,但作为备用提示
console.warn('无法在新标签页中打开链接:GM_openInTab 和 window.open 均不可用。');
}
}
}, true); // 使用捕获阶段监听事件,以便在链接默认行为或其他脚本处理之前捕获点击
})();