【问题标题】:Can I inject a CSS file programmatically using a content script js file?我可以使用内容脚本 js 文件以编程方式注入 CSS 文件吗?
【发布时间】:2012-03-09 20:12:03
【问题描述】:

我可以使用内容脚本 js 文件以编程方式注入 CSS 文件吗?

当 js 文件链接到我的 popup.html 时,我可以注入 css。问题是我必须单击按钮打开弹出窗口以注入 css。我希望它在后台自动发生。

我的代码中发生了什么...

  1. 通过 XMLHttpRequest 从 MySQL 数据库中获取变量
  2. 调用函数“processdata()”
  3. "processdata" 将处理来自 XMLHttpRequest 的数据。更具体地说,拆分变量,将其放入 2 个不同的变量中并使其成为全局变量
  4. 我调用函数“click()”
  5. "click" 然后会在 1250 毫秒后使用 setTimeout 设置 css
  6. 我使用 chrome.tabs.insertCSS 来插入 css。 css 名称是变量,“currenttheme”

正如我之前提到的,它确实可以使用弹出窗口。但是必须在注入 CSS 之前打开弹出窗口。

我如何让这一切自动发生,无需任何用户交互?

这是我的代码:

    function getData() {
if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        user_data = xmlhttp.responseText;
        window.user_data = user_data;
        processdata();
        }
      }
    xmlhttp.open("GET","http://localhost:8888/g_dta.php",true);
    xmlhttp.send();
}

getData();

function processdata() {
  var downdata = user_data.split('|||||');
  var installedthemes = downdata[0];
  var currenttheme = downdata[1].toString();
  window.currenttheme = currenttheme;
  click();
  }

function click(e) { 
      function setCSS() {
          chrome.tabs.insertCSS(null, {file:currenttheme + ".css"});
          }
      setTimeout(function(){setCSS()}, 1250);
      document.getElementById('iFrameLocation').innerHTML = "<iframe src='http://localhost:8888/wr_dta.php?newid="+e.target.id+"'></iframe>";
      getData();
}

document.addEventListener('DOMContentLoaded', function () {
  var divs = document.querySelectorAll('div');
  for (var i = 0; i < divs.length; i++) {
    divs[i].addEventListener('click', click);
  }
});

【问题讨论】:

    标签: javascript google-chrome google-chrome-extension google-chrome-devtools


    【解决方案1】:

    扩展闪烁

    对生态系统的创伤不难修复

    前言:

    在将 css 添加到页面的许多方法中,其中大多数会导致屏幕闪烁 - 最初显示页面时未应用 css,然后再应用它。我尝试了几种方法,以下是我的发现。

    要点

    您需要在 Content script injected on document_start 中附加 CSS &lt;link&gt; 或 &lt;style&gt; 标记

    该代码如下所示:

    var link = document.createElement('link');
    link.href =  chrome.runtime.getURL('main.css');
      //chrome-extension://<extension id>/main.css
    link.rel = 'stylesheet';
    document.documentElement.insertBefore(link);
    

    对于一些动态的 CSS 代码:

    var customStyles = document.createElement('style'); 
    customStyles.appendChild(document.createTextNode(
       'body { background-color: ' + localStorage.getItem('background-color') + '}'
    ));
    document.documentElement.insertBefore(customStyles); 
    

    在document_start 上的脚本中执行此操作可确保没有闪烁!

    推理

    在这个 JavaScript 文件中,您可以处理任意数量的程序化事情。 manifest.json 中提供的 URL 模式匹配非常有限,但在这里您实际上可以查看一个 url 的所有 ?query_string 和 #hash,并使用完整的正则表达式和字符串操作来决定是否注入 CSS。该 CSS 也可以基于设置,和/或与后台页面的消息协调。

    离别词

    • 不要使用.insertCSS,你会注意到闪烁。

    【讨论】:

    • 我推荐chrome.extension.getURL('/mod/style.css'),而不是硬编码的chrome-extension://... 协议+主机。
    • 我知道,这更像是一篇博文,但请告诉我你们的想法!
    • chrome.extension.getURL() 自 Chrome 58 起已弃用。developer.chrome.com/extensions/extension#method-getURL
    • document.documentElement.insertBefore(link, null) 否则你会得到 Uncaught (in promise) TypeError: Failed to execute 'insertBefore' on 'Node': 需要 2 个参数,但只有 1 个存在。
    • 为什么使用insertBefore,而不是在后面追加?
    【解决方案2】:

    很简单,您可以添加到清单的权限字段中:参见web_accessible_resources

     , "web_accessible_resources": [
            "mystyle.css"
        ]
    

    并将其添加到content_scripts

    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "css": ["mystyle.css"],
            "js": ["jquery-1.10.2.min.js","content.js","my.min.js"]
        }],
    

    您还可以使用 Programmatic injection 和 insertCSS() 添加相同的内容。

    chrome.tabs.insertCSS(integer tabId, object details, function callback)
    

    【讨论】:

      【解决方案3】:

      您可以通过编程方式创建一个新的&lt;link&gt; 标记并将其添加到&lt;head&gt; 部分,就像动态加载JS 文件一样。

      var link = document.createElement("link");
      link.href = "http://example.com/mystyle.css";
      link.type = "text/css";
      link.rel = "stylesheet";
      document.getElementsByTagName("head")[0].appendChild(link);
      

      这里是 an article 的主题。

      【讨论】:

      • 我的印象是你做的很简单......就像不费吹灰之力地用裁判做出答案。专家很容易得到好的答案...
      • @CrisStringfellow - 谢谢克里斯。我知道动态添加脚本标签的代码,并认为它可能与 CSS 文件相同。我进行了一次谷歌搜索以确认这一点,然后写下了答案。
      • 为我工作。在单页上测试外部 CSS 的好方法
      • 在链接外部样式表之前,我们正在等待文档头部(因此可能是整个文档)呈现在屏幕上,这不会造成闪烁或 FOUC 吗?
      • @zr0gravity7 - 是的,当新的 CSS 加载时,它可能会导致渲染发生变化。根据它首先被动态加载的确切原因以及它包含的内容,有多种策略可以防止这种情况发生。最简单的想法是,在加载此样式表之前,内容默认为不可见。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2017-11-22
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      相关资源
      最近更新 更多