通过GreaseMonKey脚本动态更换页面元素(甚至页面加载)

发布于 2025-01-31 03:47:12 字数 510 浏览 2 评论 0原文

我具有以下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];
      }
    }
  }
}

即使在一个页面被满载后,我也希望它能正常工作(换句话说,使用该页面JS后负载出现的动态生成的HTML元素)。

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

使用JavaScript + GreaseMonKey我该怎么做? 谢谢。

I have the following javascript function:

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];
      }
    }
  }
}

I want it to work even after a page is fully loaded (in other words, work with dynamically generated html elements that appeared post-load by the page's js).

It could either be by running the function every x seconds or when a certain element xpath is detected within the page, or every time a certain image url is loaded within the browser (which is my main goal here).

What can I do to achieve this using javascript + greasemonkey?
Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟织青萝梦 2025-02-07 03:47:12

您是否尝试过在浏览器的终端运行代码,以查看涉及GreaseMonKey的无需涉及的情况吗?

至于您的问题 - 您可以使用setInterval每一个x量的时间运行给定代码,或者可以使用突变处理器来监视对网页dom的更改。在我看来,SetInterval足以完成这项工作,您可以尝试学习突变处理器将来的工作方式。

因此,重写您的代码:

  // 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分钟的间隔很长,请根据需要进行调整)。

Have you tried running your code in the browser's terminal to see if it works without greasemonkey involved?

As to your question - you could either use setInterval to run given code every x amount of time or you could use the MutationObserver to monitor changes to the webpage's dom. In my opinion setInterval is good enough for the job, you can try learning how the MutationObserver works in the future.

So rewriting your code:

  // 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);

You could make more complex version by tracking the img count and only doing the imageLookop if their number increases. This would be a big optimization and would allow you to run the query more frequently (though 5 minutes is pretty long interval, adjust as required).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文