首页 > 解决方案 > 如何将用户脚本注入嵌入式网页内容?

问题描述

单击链接以打开嵌入式网页后,我想注入一个用户脚本。具体来说,我想知道我应该如何注入这个脚本:

Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)).forEach(i => i.style.display = 'none');

Array.from(document.querySelectorAll('div')).filter(i => /moreComments-/.test(i.id)).forEach(i => i.querySelector('p').click());

setTimeout(function() {
    Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)).forEach(i => i.style.display = 'none');
},7000)

进入所有可嵌入的 Reddit 子页面,即从 subreddit 的主页加载的所有链接线程:

一张图片说明了嵌入式 Reddit 子页面与标准完全加载页面的对比

我认为这需要一个事件侦听器或MutationObserver,但我不知道如何指定解决方案。阅读 Reddit 源代码非常令人困惑,而且我不是编码员。这只是我认为对我自己和其他日常网络用户有用的知识。

解决此类问题的正确步骤是什么?我应该考虑什么样的代码?

标签: javascripteventsdynamicgoogle-chrome-extensionuser-defined-functions

解决方案


您需要在选定的一组页面节点上处理用户脚本。因为您的代码在每个页面加载事件中只执行一次,所以稍后动态加载的节点不受影响。

有几种方法可以实现您的目标。最简单的方法之一是使用setInterval函数。这会定期调用您的函数(通过使用合理的时间跨度,例如 500 毫秒)。使用此功能,您必须选择所需的节点并仅处理新到达的节点。_is_processed您可以使用属性之类的东西来标记节点的 DOM 对象。最后,这可以包装到另一个函数中,比如doForEachOnce. 例如:

function doForEachOnce(list,theFunc) {
    list.forEach(i => {
        if (!i._is_processed) { i._is_processed = true; return theFunc(i); } else { return null; }
    });
}

doForEachOnce(Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)), i => i.style.display = 'none');
doForEachOnce(Array.from(document.querySelectorAll('div')).filter(i => /moreComments-/.test(i.id)), i => i.querySelector('p').click());

setInterval(function() {
  doForEachOnce(Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)), i => i.style.display = 'none');
},500);

我用 Tampermonkey 成功测试了这个用户脚本。它扩展所有评论,在页面加载时隐藏业力,然后为每个新来者再次隐藏业力。希望这是你需要的。


推荐阅读