在Chrome扩展程序中读取CSS文档

时间:2012-02-16 23:57:51

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

我正在尝试使用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扩展的内容脚本中时失败了。有人能知道为什么吗?

4 个答案:

答案 0 :(得分:4)

那就是为什么,但为了好玩和兴趣(以前没有用样式表做过任何事情)我想我做了一个如何.... manifest.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会在注入的脚本中执行大部分检查,然后通过div及其事件传回结果。但我想看看我是否可以使用内容脚本中的dom方法来完成css,这是我能想到的唯一方法。我不喜欢将规则插入页面的想法,但无法想象其他任何方式。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

要获取所有外部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]);
                }
            }
        });
    }
);

答案 3 :(得分:0)

答案很晚,但我想我可以提供帮助。访问受COR保护的外部工作表的cssRules的一种方法是使用Yahoo的YQL服务。我已将其合并到Chrome的开发者工具扩展中,用于捕获页面片段的样式和标记。扩展程序位于Chrome Web Store,位于Github

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

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

Extension Screenshot