从chrome扩展更改外部CSS

时间:2017-11-19 03:01:58

标签: javascript css google-chrome-extension

我正在编写一个chrome扩展,需要迭代注入页面中的所有样式表并修改某些样式。

我迭代/修改样式,例如:

const iterate = (doc, f) => {
  for (const styleSheet of doc.styleSheets) {
    const rules = styleSheet.rules || styleSheet.cssRules;
    if (!rules) continue;
    for (const cssRule of rules) {
      if (!cssRule.style) continue;
      const selector = cssRule.selectorText, style = cssRule.style;
      if (!selector || !style.cssText) continue;
      f(style);
    }
  }
}

document.addEventListener("DOMContentLoaded", e => {
  setTimeout(() => {
    iterate(document, style => {
      if (style.getPropertyValue('background-color')) style.setProperty('background-color', 'yellow');
    });
  }, 1000);
});
div {
  background-color: red;
}
<div>hello</div>

我遇到的问题是外部css似乎没有被包括在内。

例如,如果我将扩展注入stackoverflow.com,其中包含:

<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/stackoverflow/all.css?v=cfd0b49a38a7">

然后,不会迭代all.css中的样式。

如何迭代/修改外部样式?

注1 - 我尝试手动获取这些链接rel并将它们放入内部样式标记中但会破坏这些文件中的任何相对URL(即background-image: url('path/image.jpg')

注2 - 我的清单有"permissions": [ "http://*/*", "https://*/*" ]

注意3 - 因为这是针对Chrome扩展程序的,我对仅使用Chrome的解决方案感到满意

2 个答案:

答案 0 :(得分:0)

这可能是您的示例代码中的一个错误,但很明显,它不可能在 DOMContentLoaded事件+ 1秒之前注入和获取样式表。尝试将setTimeout等待更改为 20秒,看看会发生什么。

如果这样可以解决您的问题,那么下一步就是创建一个更好的解决方案,等待样式表在迭代之前显示出来。

答案 1 :(得分:0)

您的扩展程序的权限不会覆盖页面对页面上已有内容的权限,例如您尝试阅读和修改的样式表。

您可以做的是获取外部样式表,例如:

const response = await fetch('https://cdn.sstatic.net/Sites/stackoverflow/all.css');
const css = await response.text();
const style = document.createElement('style');
style.textContent = css;

然后您可以迭代这个新的 style 元素中的规则并只将必要的样式注入页面,因此您可能不必担心更改样式表中的亲戚 URL。如果这是一个问题,您还必须手动重写这些 URL。

注意:现在您可能还会遇到上述代码的 CORB 问题,因此您必须fetch 通过后台:https://stackoverflow.com/a/56929473/288906