强制页面在新标签页打开

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

当前为 2024-05-24 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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();
})();