通过 greasemonkey 脚本动态替换页面元素(甚至 post 页面加载)

Replacing page elements dynamically through a greasemonkey script (even post page load)

我有以下 javascript 功能:

function actionFunction() {
  let lookup_table = {
    'imageurl1': "imageurl2",
  };

  for (let image of document.getElementsByTagName("img")) {
    for (let query in lookup_table) {
      if (image.src == query) {
        image.src = lookup_table[query];
      }
    }
  }
}

我希望它即使在页面完全加载后也能正常工作(换句话说,使用动态生成的 html 元素出现 post- 由页面的 js 加载)。

它可以是 运行 每 x 秒的函数或当在页面中检测到某个元素 xpath 时,或者每次在浏览器中加载某个图像 url 时(这是我的主要目标)。

如何使用 javascript + greasemonkey 实现此目的? 谢谢。

您是否尝试过 运行在浏览器的终端中运行您的代码,看看它是否可以在不涉及 greasemonkey 的情况下运行?

关于你的问题 - 你可以使用 setInterval 来 运行 每 x 时间给定的代码,或者你可以使用 MutationObserver 来监视网页 dom 的变化。在我看来 setInterval 足以胜任这项工作,您可以在以后尝试学习 MutationObserver 的工作原理。

所以重写你的代码:

  // arrow function - doesn't lose this value and execution context
  // setInterval executes in a different context than the enclosing scope which makes functions lose this reference
  // which results in being unable to access the document object
  // and also window as they all descend from global scope which is lost
  // you also wouldn't be able to use console object
  // fortunately we have arrow functions
  // because arrow functions establish this based on the scope the arrow function is defined within
  // which in most cases is global scope
  // so we have access to all objects and their methods

  const doImageLookup = () => {
    const lookup_table = {
    'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png': 'https://www.google.com/logos/doodles/2022/gama-pehlwans-144th-birthday-6753651837109412-2x.png',
};
    const imgElementsCollection = document.getElementsByTagName('img');
    [...imgElementsCollection].forEach((imgElement) => {
      Object.entries(lookup_table).forEach(([key, value]) => {
        const query = key; // key and value describe object's properties
        const replacement = value; // here object is used in an unusual way, i would advise to use array of {query, replacement} objects instead
        if (imgElement.src === query) {
          imgElement.src = replacement;
        }
      });
    });
  };
  const FIVE_MINUTES = 300000; // ms
  setInterval(doImageLookup, FIVE_MINUTES);

您可以通过跟踪 img 计数并仅在其数量增加时执行 imageLookop 来制作更复杂的版本。这将是一个很大的优化,可以让您 运行 更频繁地查询(尽管 5 分钟是相当长的间隔,请根据需要进行调整)。