How to display all CSS selectors & properties in a textarea?

后端 未结 1 1645
终归单人心
终归单人心 2020-12-20 09:49

I am trying to display a set of CSS properties in a textarea using JavaScript:

var exampleone = document.getElementBy         


        
相关标签:
1条回答
  • 2020-12-20 10:36

    Updated answer

    There is a helpful topic here:

    How to get the applied style from an element, excluding the default user agent styles

    I tried to enhance the solution provided in this topic to better fit your needs by…

    • Adding a parameter to be able to choose whether or not to include inline style,
    • Adding a function to correctly indent the styles,
    • Trying to simplify some code.

    var proto = Element.prototype;
    var slice = Function.call.bind(Array.prototype.slice);
    var matches = Function.call.bind(proto.matchesSelector ||
      proto.mozMatchesSelector || proto.webkitMatchesSelector ||
      proto.msMatchesSelector || proto.oMatchesSelector);
    
    // Returns true if a DOM Element matches a cssRule
    var elementMatchCSSRule = function(element, cssRule) {
      // console.log(cssRule) //.selectorText.split(":")[0]); // Testing to add hover
      return matches(element, cssRule.selectorText);
    };
    
    // Returns true if a property is defined in a cssRule
    var propertyInCSSRule = function(prop, cssRule) {
      return prop in cssRule.style && cssRule.style[prop] !== '';
    };
    
    // Here we get the cssRules across all the stylesheets in one array
    var cssRules = slice(document.styleSheets).reduce(function(rules, styleSheet) {
      return rules.concat(slice(styleSheet.cssRules));
    }, []);
    
    // Get only the css rules that matches that element
    var getAppliedCSS = function(elm) {
      var elementRules = cssRules.filter(elementMatchCSSRule.bind(null, elm));
      var rules = [];
      if (elementRules.length) {
        for (i = 0; i < elementRules.length; i++) {
          rules.push({
            order: i,
            text: elementRules[i].cssText
          })
        }
      }
      return rules;
    }
    
    // TAKIT: Added this function to indent correctly
    function indentAsCSS(str) {
      return str.replace(/([{;}])/g, "$1\n ").replace(/(\n[ ]+})/g, "\n}");
    }
    
    function getStyle(elm, lookInHTML = false) { // TAKIT: Added the new parameter here
      var rules = getAppliedCSS(elm);
      var str = '';
      for (i = 0; i < rules.length; i++) {
        var r = rules[i];
        str += '/* CSS styling #' + r.order + ' */\n' + r.text;
      }
      
      // TAKIT: Moved and simplified the below from the other function to here
      if (lookInHTML && elm.getAttribute('style')) // TAKIT: Using the new parameter
        str += '\n/* Inline styling */\n' + elm.getAttribute('style');
      
      return indentAsCSS(str);
    }
    
    // Output in textarea
    var exone = document.getElementById("exone");
    var result = document.getElementById("result");
    result.value = getStyle(exone, true); // TAKIT: Using the new parameter for inline style
    #exone {
      border-style: solid;
      border-width: 2px;
      border-color: rgba(57, 165, 255, 1.00);
      width: 150px;
      height: 30px;
      position: relative;
      text-align: center;
      background-color: transparent;
      color: black;
    }
    
    #exone:hover {
      cursor: pointer;
      background-color: rgba(57, 165, 255, 1.00);
      color: white;
    }
    
    #result {
      width: 90%;
      height: 240px;
    }
    <div id="exone" style="opacity: 0.95;"></div>
    <textarea id="result"></textarea>

    (I'm trying to add the :hover style to the output too, but I can't make it to work)

    ⋅ ⋅ ⋅


    Old answer
    (When I hadn't found anything helpful yet)

    As the .getComputedStyle doesn't make any difference between the one that are present in the CSS and the other ones, it seems complicated to differenciate them.

    So, here is an attempt of that:

    • I've made a loop to compare the element exone with another reference element that has not been stylized using CSS,
    • It seems that the element we take in reference must be on the page to effectively compare them, so I've put it in the HTML.
    • In the loop, if the values are the same, that must mean that both of them are not stylized, so, we skip to the next item.

    I ended-up with that snippet:

    // Get style of our example element
    var exampleone = document.getElementById('exone');
    var styles_one = window.getComputedStyle(exampleone);
    
    // Get style of a reference element without CSS
    var reference = document.getElementById('exref');
    var styles_ref = window.getComputedStyle(reference);
    
    // Loop and compare our example element with the reference element
    var results = {};
    for (var key in styles_ref) {
      if(key.includes('webkit')) continue;             // Next if webkit prefix
      if(styles_one[key] == styles_ref[key]) continue; // Next if same value as the ref
      results[key] = styles_one[key];                  // Copy value in results[key]
    }
    delete results.cssText; // Useless in our case
    
    // Output in console
    console.log(results);
    #exone {
      border-style: solid;
      border-width: 2px;
      border-color: rgba(57, 165, 255, 1.00);
      width: 150px;
      height: 30px;
      position: relative;
      text-align: center;
      background-color: transparent;
      color: black;
    }
    
    #exone:hover {
      cursor: pointer;
      background-color: rgba(57, 165, 255, 1.00);
      color: white;
    }
    <div id="exone"></div>
    <div id="exref"></div>

    The console should display only the CSS that differs from the not stylized reference element… So, this must come from the CSS!

    Now, we only need to format a little this output and put it in a textarea.

    Feel free to comment.

    Hope it helps.

    0 讨论(0)
提交回复
热议问题