强制页面在新标签页打开

强制链接在新标签页打开,脚本采用白名单的模式,在油猴自带的菜单里面控制开关

当前为 2023-08-05 提交的版本,查看 最新版本

// ==UserScript==
// @name         强制页面在新标签页打开
// @namespace    http://tampermonkey.net/
// @version      0.1.4
// @description  强制链接在新标签页打开,脚本采用白名单的模式,在油猴自带的菜单里面控制开关
// @author       You
// @match        http://*/*
// @match        https://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=openai.com
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant unsafeWindow
// @license MIT
// ==/UserScript==

(function () {
	"use strict";
	
	//网页白名单管理
	function whiteListManage() {
		let menuId;
		//开启
		function open() {
			GM_unregisterMenuCommand(menuId);
			hookPageWhenDomChange();
			hookPage();
			localStorage.setItem("whiteList_a5c9f2b1", "true");
			GM_registerMenuCommand("关闭", function () {
				close();
			});
		}
		//关闭
		function close() {
			GM_unregisterMenuCommand(menuId);
			localStorage.setItem("whiteList_a5c9f2b1", "false");
			location.reload();
		}
		
		let whiteList = localStorage.getItem("whiteList_a5c9f2b1");
		if (!whiteList || whiteList === "false") {
			menuId = GM_registerMenuCommand("开启", open);
		} else if (whiteList === "true") {
			hookPageWhenDomChange();
			hookPage();
			menuId = GM_registerMenuCommand("关闭", close);
		}
	}
	
	//修改页面以实现链接在新标签页打开
	function hookPage() {
		hookWindowOpen();
		hookATag();
	}
	
	function hookATag() {
		// 获取页面上的所有链接元素
		let links = document.getElementsByTagName("a");
		for (let i = 0; i < links.length; i++) {
			//如果标签的href属性为空或者是javascript:开头的则跳过
			if (!links[i].href || links[i].href.startsWith("javascript:") || links[i].href.startsWith("#")) {
				continue;
			}
			// 遍历每个链接元素并添加目标属性
			links[i].setAttribute("target", "_blank");
			//给标签添加点击事件,点击后标红
			links[i].addEventListener("click", function () {
				this.style.color = "darkred";
			});
		}
	}
	
	function hookWindowOpen() {
		// 保存原始的 window.open 方法的引用
		let originalOpen = unsafeWindow.open;
		// 重写 window.open 方法
		unsafeWindow.open = function (url, target, features) {
			// 在新标签页中打开链接
			originalOpen.call(this, url, "_blank", features);
		};
	}
	
	//监听dom节点变化以应对异步刷新的场景,一旦dom节点发生变化则重新执行hookPage
	function hookPageWhenDomChange() {
		let MutationObserver =
			window.MutationObserver || window.WebKitMutationObserver;
		let observer = new MutationObserver(function (mutations) {
			mutations.forEach(function (mutation) {
				hookATag();
			});
		});
		observer.observe(document.body, {
			childList: true, // 观察目标子节点的变化,是否有添加或者删除
			subtree: true, // 观察后代节点,默认为 false
			attributes: false, // 观察属性变动
		});
	}
	
	function init() {
		whiteListManage();
	}
	init();
})();