【问题标题】:Reading documents CSS in Chrome Extension在 Chrome 扩展中读取文档 CSS
【发布时间】:2012-03-08 10:10:16
【问题描述】:

我正在尝试使用 chrome 扩展读取页面 CSS。这就是我的内容脚本中的内容:

   var allSheets = document.styleSheets;
     for (var i = 0; i < allSheets.length; ++i) {
      var sheet = allSheets[i];
          var src = sheet.href;
      var rules = sheet.cssRules || sheet.rules;
     }

由于某种原因,规则总是空的。我确实得到了“src”变量中使用的所有 CSS 文件。但是规则总是为空。当我在 HTML 页面上将其作为单独的 javascript 尝试时,它的工作原理。但是当我把它放在我的 chrome 扩展的内容脚本中时失败了。有人能告诉我为什么吗?

【问题讨论】:

  • 我已经在开发者工具栏中测试了您的代码,我可以看到“cssRules”和“rules”属性始终为空。更重要的是——你想达到什么目标?
  • 读取所有 CSS 并解析它们并处理 CSS 属性..
  • 不想学究气,但你的“匹配”设置正确吗?你能把它设置为 '*' 看看会发生什么吗?
  • 哦..明白了..是的..设置为:“匹配”:[“http://*/*”,“https://*/*”],
  • 我也遇到了问题。目前我不知道,但使用 xmlhttprequest 再次加载它并检索响应文本。

标签: css google-chrome google-chrome-extension


【解决方案1】:

只是一个猜测,但由于 chrome 扩展是基于 Javascript 的,它们可能存在跨域问题。当以编程方式尝试从另一个域获取样式表时,Chrome 会将规则和 cssRules 设置为 null。

【讨论】:

  • 不是真的,这是一个安全风险。你想通过阅读规则来完成什么?
  • 我正在尝试读取所有 CSS 属性并使用这些属性执行一些只读操作。所以你说没有办法在 chrome 插件上做到这一点? ;'(
  • 如果您可以控制与您的扩展程序通信的服务器,那么这是可能的。否则,如果没有遍历 DOM 中的对象并计算它们的样式,恐怕你就不走运了。
  • Chrome 允许您在页面脚本中访问 DOM。
【解决方案2】:

这就是为什么,但为了好玩和感兴趣(以前从未对样式表做过任何事情),我想 Id 做一个 How....
ma​​nifest.json

{
    "name": "Get all css rules in stylesheets",
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js" : ["myscript.js"],
            "run_at":"document_end"
        }
    ],
    "permissions": [
        "tabs", "<all_urls>"
    ],
    "version":"1.0"
}

myscript.js

// Create the div we use for communication
 var comDiv = document.createElement('div');
 comDiv.setAttribute("id", "myCustomEventDiv");
 document.body.appendChild(comDiv);

// Utitlity function to insert some js into the page, execute it and then remove it
function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}


// function that gets inserted into the page
// iterates through all style sheets and collects their rules
// then sticks them in the comDiv and dispatchs the event that the content script listens for
getCSS=function (){
   var rules = '';

   // Create the event that the content script listens for
   var customEvent = document.createEvent('Event');
   customEvent.initEvent('myCustomEvent', true, true);

   var hiddenDiv = document.getElementById('myCustomEventDiv');
   var rules ='';
   var allSheets = document.styleSheets;
   for (var i = 0; i < allSheets.length; ++i) {
      var sheet = allSheets[i];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         rules = rules +'\n'+ sheet.cssRules[z].cssText;
      }
   }
   hiddenDiv.innerText = rules;
   hiddenDiv.dispatchEvent(customEvent);
}

// puts the rules back in the page in a style sheet that the content script can iterate through
// youd probably do most of this in the injected script normally and pass your results back through the comDiv....Im just having fun
document.getElementById('myCustomEventDiv').addEventListener('myCustomEvent', function() {
   var eventData = document.getElementById('myCustomEventDiv').innerText;
   document.getElementById('myCustomEventDiv').innerText='';

   var style = document.createElement('style');
   style.type = 'text/css';
   style.innerText=eventData;
   style = document.head.appendChild(style);
      var sheet = document.styleSheets[document.styleSheets.length-1];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         console.log(sheet.cssRules[z].selectorText +' {\n');
         for (var y = 0; y <= sheet.cssRules[z].style.length-1; y++) {
            console.log('  '+sheet.cssRules[z].style[y] + ' : ' + sheet.cssRules[z].style.getPropertyValue(sheet.cssRules[z].style[y])+';\n');
         };
         console.log('}\n');
      };

   // Clean up
   document.head.removeChild(style);
   document.body.removeChild(document.getElementById('myCustomEventDiv'));
});

exec(getCSS);

在这个问题的情况下,Id prolly 在注入的脚本中进行大部分检查,然后将结果通过 div 及其事件传回。但是我想看看我是否可以使用内容脚本中的 dom 方法来遍历 css,这是我能想到的唯一方法。我不喜欢将规则重新插入页面的想法,但想不出任何其他方法。

【讨论】:

  • 太酷了 :) .. 我确实试过这个,但由于某种原因,外部 CSS 没有被读取。只有内联的是。知道为什么吗?但是喜欢这种方法..太棒了:)
  • 对于内部样式表,您可以直接访问它的内容。
  • 对于外部样式表,您不能将其内容读取为安全风险。
【解决方案3】:

回答晚了,但我想我能帮上忙。访问受 COR 保护的外部工作表的 cssRules 的一种方法是使用 Yahoo 的 YQL 服务。我已将它合并到 Chrome 的开发人员工具扩展中,用于捕获页面片段的样式和标记。扩展位于Chrome Web Store 和Github。

从 Github 获取源代码并查看 content.js 脚本以了解如何使用 YQL。基本上,您将对 YQL 进行 AJAX 调用,它会为您获取 CSS。您需要获取 CSS 内容并将其作为嵌入式样式标记注入页面或使用 JavaScript 解析 CSS(有一些库用于此目的)。如果您选择将它们注入回文档中,请确保将新样式块设置为禁用,以免破坏页面的呈现。

扩展程序本身可能对您有用:

【讨论】:

    【解决方案4】:

    要获取所有外部 css 和所有内部 css 文件,您可以使用 devtools API。如果你想在 chrome 扩展中使用它,你需要将 devtool 连接到你的 chrome 扩展中。此代码将起作用

    chrome.devtools.panels.create(
        'my chrome extension',
        'icon.png',
        'index.html',
         function(panel) {
            var initial_resources = {};
    
            // collect our current resources
            chrome.devtools.inspectedWindow.getResources(function(resources) {
                for (var i = 0, c = resources.length; i < c; i++) {
                    if (resources[i].type == 'stylesheet') {
                        // use a self invoking function here to make sure the correct
                        // instance of `resource` is used in the callback
                        (function(resource) {
                            resource.getContent(function(content, encoding) {
                                initial_resources[resource.url] = content;
                            });
                        })(resources[i]);
                    }
                }
            });
        }
    );
    

    【讨论】:

    • 请检查:developer.chrome.com/extensions/devtools chrome.devtools.* API 模块仅适用于在 DevTools 窗口中加载的页面。内容脚本和其他扩展页面没有这些 API。因此,API 仅在 DevTools 窗口的生命周期内可用。
    猜你喜欢
    • 2015-05-05
    • 2011-10-12
    • 2012-07-02
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多