chrome 扩展在加载 dom 之前注入动态 css

Kat*_*tie 6 javascript jquery google-chrome google-chrome-extension

我正在构建一个 chrome 扩展,我想storage.sync.get在用户访问该网页时将动态(来自)css 注入网页。使用我当前的实现,它在技术上是有效的,但是,页面加载,加载后它会注入新的 css,这使得它看起来非常慢。我想在 dom 加载之前加载 css。那可能吗?

这是我目前拥有它的方式:

注入.js:

chrome.storage.sync.get("color", function(storedTheme) {
     $('.theme-wrap').removeClass('selected');
     $('.' + storedTheme.color).addClass('selected');
     path = chrome.extension.getURL("src/options/themes/" + storedTheme.color + ".css");
      $('<link/>', {
      rel: 'stylesheet',
      type: 'text/css',
      href: path
    }).appendTo('head');
});
Run Code Online (Sandbox Code Playgroud)

这是我的 manifest.json content_script 信息:

"content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "css": ["src/inject/inject.css", "src/inject/font-awesome.min.css"],
    "js": ["js/jquery/jquery.min.js", "src/inject/inject.js"],
    "run_at" : "document_end"
 }]
Run Code Online (Sandbox Code Playgroud)

src/inject/inject.css似乎DOM,这正是我想要的东西之前加载,但我希望它为用户指定的css文件的工作。有谁知道我怎么能做到这一点?谢谢

Hai*_* Ai 7

您已"run_at": "document_end"在您的 中定义manifest.json,这意味着在 DOM 完成后inject.css立即注入,但在图像和框架等子资源加载之前。

看看run_at,你可以设置"run_at": "document_start",这意味着文件在来自 css 的任何文件之后注入,但在构建任何其他 DOM或运行任何其他脚本之前。但是,在这种情况下,如果您的异步方法 ( chrome.storage.sync.get) 执行得足够快,则由于未构造 DOM,因此无法获得正确的结果。

我建议您inject.css在构建 DOM 之前注入,然后侦听DOMContentLoaded事件以执行您的inject.js逻辑。

DOMContentLoaded 事件在初始 HTML 文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载。

清单文件

"content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "css": ["src/inject/inject.css", "src/inject/font-awesome.min.css"],
    "js": ["js/jquery/jquery.min.js", "src/inject/inject.js"],
    "run_at" : "document_start"
 }]
Run Code Online (Sandbox Code Playgroud)

注入.js

window.addEventListener("DOMContentLoaded", function() {
    chrome.storage.sync.get("color", function(storedTheme) {
        $('.theme-wrap').removeClass('selected');
        $('.' + storedTheme.color).addClass('selected');
        path = chrome.runtime.getURL("src/options/themes/" + storedTheme.color + ".css");
        $('<link/>', {
            rel: 'stylesheet',
            type: 'text/css',
            href: path
        }).appendTo('head');
    });
}, false);
Run Code Online (Sandbox Code Playgroud)