强制页面在新标签页打开

为了避免误触需要在油猴菜单里输入生效的dom元素的选择器,如果想要整个网页都生效,只需填入 body 即可

目前為 2024-05-24 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         强制页面在新标签页打开
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  为了避免误触需要在油猴菜单里输入生效的dom元素的选择器,如果想要整个网页都生效,只需填入 body 即可
// @author       meteora
// @match        http://*/*
// @license MIT
// @match        https://*/*
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant unsafeWindow
// ==/UserScript==

(function () {
  "use strict";
  //排除iframe
  if (window.self !== window.top) {
    return;
  }

  let domListText = localStorage.getItem("domListText")
    ? localStorage.getItem("domListText")
    : "";
  let domList = [];

  function hookATag() {
    // 获取页面上的所有链接元素
    for (let domListElement of domList) {
      let links = domListElement.getElementsByTagName("a");
      for (let i = 0; i < links.length; i++) {
        // 遍历每个链接元素并添加目标属性
        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, // 观察属性变动
    });
  }

  //显示文本输入框浮窗,用于接收用户输入的需要生效的dom选择器
  function showInputTextarea() {
    const dom = `
<div style="position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 9999; background-color: white; padding: 20px; border: 1px solid #ccc; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); " id="container-zuc08">
  <textarea id="inputTextarea-zuc08" style="width: 600px; height: 300px; border: 1px solid #ccc; border-radius: 5px; padding: 5px" placeholder="在此输入要生效的dom元素选择器,多个用空格间隔开"></textarea>
  
  <div style="display: flex; margin-top: 10px">
    <div style="padding: 5px 30px; width: max-content; background: #007bff; color: white; border-radius: 5px; cursor: pointer;" id="confirm-btn-zuc08">确定并刷新页面生效</div>
    <div style="margin-left: 10px; padding: 5px 30px; width: max-content; background: dimgray; color: white; border-radius: 5px; cursor: pointer" id="cancel-btn-zuc08">取消</div>
  </div>
</div>
`;
    document.body.insertAdjacentHTML("beforeend", dom);
    const inputTextarea = document.getElementById("inputTextarea-zuc08");
    inputTextarea.value = domListText; //回显文本内容
    inputTextarea.focus(); //自动聚焦
    //绑定事件
    function close() {
      document.body.removeChild(document.getElementById("container-zuc08"));
    }
    //确定按钮
    const confirmBtnDom = document.getElementById("confirm-btn-zuc08");
    confirmBtnDom.addEventListener("click", function () {
      domListText = inputTextarea.value;
      localStorage.setItem("domListText", domListText);
      close();
      //刷新页面
      location.reload();
    });
    //取消按钮
    const cancelBtnDom = document.getElementById("cancel-btn-zuc08");
    cancelBtnDom.addEventListener("click", function () {
      close();
    });
  }

  function init() {
    //注册油猴菜单,呼出文本输入框
    GM_registerMenuCommand(
      "设置新标签页打开链接的dom选择器",
      showInputTextarea,
    );
    //通过换行符切割 domListText 里的内容
    if (domListText) {
      const temp = domListText.split("\n");
      for (let string of temp) {
        const innerDomList = document.querySelectorAll(string);
        for (let innerDomListElement of innerDomList) {
          domList.push(innerDomListElement);
        }
      }
      hookATag();
    }
  }
  init();
})();