开发者问题收集

使用 Tampermonkey 更改网站文本

2019-12-20
976

所以基本上我想将 W 文本更改为 B。我的以下代码运行良好,但刷新页面时会出现延迟,页面会显示 W 文本,然后将其替换为 B。我的第二个问题是每刷新 20 次左右,B 文本不会替换原始文本。有人可以帮我修复我的代码,以免犯这两个错误吗?谢谢。

window.onload = function () {
    /* Add your logic here */
    var my_div = document.getElementsByClassName('c')[3]
    my_div.firstChild.nodeValue = 'B'
}
1个回答

一旦页面上的 所有 资源下载完成后, onload 处理程序就会运行。在包含图像和外部脚本等的较大页面上,这可能需要一段时间,特别是在连接不良的情况下。

改为附加一个 DOMContentLoaded 监听器,它将在浏览器下载并解析 DOM 结构后立即运行。

如果在用户脚本运行时文档可能已经具有交互性,则不要附加监听器,只需运行一个立即更改文本的函数:

if (window.top === window) {
  const fn = () => {
    var my_div = document.getElementsByClassName('c')[3];
    my_div.firstChild.nodeValue='B'
  };
  if (document.readyState === 'interactive' || document.readyState === 'complete') {
    fn();
  } else {
    window.addEventListener('DOMContentLoaded', fn);
  }
}

但是链接中的文档很大,甚至 DOM 解析也需要很长时间,那么上述方法可能不够快,在这种情况下,您可以在 页面加载 开始时将 MutationObserver 附加到文档(使用 @run-at document-start 和即时脚本注入),并在文档中存在 document.getElementsByClassName('c')[3] 时立即更改它,例如这个:

// ==UserScript==
// @name             New Userscript
// @include          /^https://fork-accessuh-uh-edu-e3e0cca90dc751a6.sitemod.io/logout.phpsitemod/
// @run-at           document-start
// ==/UserScript==

const cs = document.getElementsByClassName('c');
new MutationObserver((mutations, observer) => {
  if (!cs[3]) {
    return;
  }
  cs[3].firstChild.nodeValue='B'
  observer.disconnect();
})
  .observe(document.documentElement, { childList: true, subtree: true });

document-start 并不完全可靠 - 有时需要 一些时间 才能执行此类脚本。如果您碰巧处于脚本不会立即运行的环境中,请通过 Tampermonkey 设置启用实验性即时脚本注入(配置模式:高级,滚动到最底部,注入模式:即时)。

CertainPerformance
2019-12-20