Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - How to get all styles/css (defined within internal/external document) with HTML of an element

I know that $("#divId").html() will give me innerHtml. I also need its styles (which might be defined by the means of classes) either in-line style attribute or all the styles/classes within a separate <style> tag.

Is it possible?

UPDATE
What if html is like <div id="testDiv">cfwcvb</div> and a css class for #testDiv is defined in external stylesheet?

UPDATE 2
Sorry for not clarifying this earlier

If this is my HTML

<div id="divId">
    <span class="someClass">Some innerText</span>
</div>

And styles are defined in separate style sheet or in head styles.

#divId {
    clear: both;
    padding: 3px;
    border: 2px dotted #CCC;
    font-size: 107%;
    line-height: 130%;
    width: 660px;
}
.someClass {
    color: blue;
}

Then when I try to get inner html of $("#divId").html() or call any other custom function, I need something like below

<style>
#divId {
    clear: both;
    padding: 3px;
    border: 2px dotted #CCC;
    font-size: 107%;
    line-height: 130%;
    width: 660px;
}
.someClass {
    color: blue;
}
</style>

<div id="divId">
    <span class="someClass">Some innerText</span>
</div>

UPDATE 3 for Answer by kirilloid
I ran below code in Command Window of Chrome Debugger tools for this page itself and this is what I see TypeError: Cannot read property 'rules' of undefined

function getElementChildrenAndStyles(selector) {
  var html = $(selector).get(0).outerHTML;

  selector = selector.split(",").map(function(subselector){
    return subselector + "," + subselector + " *";
  }).join(",");
  elts = $(selector);

  var rulesUsed = [];
  // main part: walking through all declared style rules
  // and checking, whether it is applied to some element
  sheets = document.styleSheets;
  for(var c = 0; c < sheets.length; c++) {
    var rules = sheets[i].rules || sheets[i].cssRules;
    for(var r = 0; r < rules.length; r++) {
      var selectorText = rules[r].selectorText;
      var matchedElts = $(selectorText);
      for (var i = 0; i < elts.length; i++) {
        if (matchedElts.index(elts[i]) != -1) {
          rulesUsed.push(CSSrule); break;
        }
      }
    }
  }
  var style = rulesUsed.map(function(cssRule){
    if ($.browser.msie) {
      var cssText = cssRule.style.cssText.toLowerCase();
    } else {
      var cssText = cssRule.cssText;
    }
    // some beautifying of css
    return cssText.replace(/(\{|;)\s+/g, "\$1\n  ").replace(/\A\s+}/, "}");
    //                 set indent for css here ^ 
  }).join("\n");
  return "<style>\n" + style + "\n</style>\n\n" + html;
};
getElementChildrenAndStyles(".post-text:first");
like image 532
IsmailS Avatar asked Jan 24 '11 11:01

IsmailS


People also ask

How can give multiple CSS properties in jQuery?

Apply multiple CSS properties using a single JQuery method CSS( {key1:val1, key2:val2....). You can apply as many properties as you like in a single call. Here you can pass key as property and val as its value as described above.

Why this is used in jQuery?

The this Keyword is a reference to DOM elements of invocation. We can call all DOM methods on it. $() is a jQuery constructor and in $(this), we are just passing this as a parameter so that we can use the jQuery function and methods.

Which jQuery method should be used to delete the element from the web page?

To remove elements and content, there are mainly two jQuery methods: remove() - Removes the selected element (and its child elements) empty() - Removes the child elements from the selected element.


2 Answers

outerHTML (not sure, you need it — just in case)

Limitations: CSSOM is used and stylesheets should be from the same origin.

function getElementChildrenAndStyles(selector) {
  var html = $(selector).outerHTML();

  selector = selector.split(",").map(function(subselector){
    return subselector + "," + subselector + " *";
  }).join(",");
  elts = $(selector);

  var rulesUsed = [];
  // main part: walking through all declared style rules
  // and checking, whether it is applied to some element
  sheets = document.styleSheets;
  for(var c = 0; c < sheets.length; c++) {
    var rules = sheets[c].rules || sheets[c].cssRules;
    for(var r = 0; r < rules.length; r++) {
      var selectorText = rules[r].selectorText;
      var matchedElts = $(selectorText);
      for (var i = 0; i < elts.length; i++) {
        if (matchedElts.index(elts[i]) != -1) {
          rulesUsed.push(rules[r]); break;
        }
      }
    }
  }
  var style = rulesUsed.map(function(cssRule){
    if (cssRule.style) {
      var cssText = cssRule.style.cssText.toLowerCase();
    } else {
      var cssText = cssRule.cssText;
    }
    // some beautifying of css
    return cssText.replace(/(\{|;)\s+/g, "\$1\n  ").replace(/\A\s+}/, "}");
    //                 set indent for css here ^ 
  }).join("\n");
  return "<style>\n" + style + "\n</style>\n\n" + html;
}

usage:

getElementChildrenAndStyles("#divId");
like image 144
kirilloid Avatar answered Sep 22 '22 11:09

kirilloid


No jQuery and no IE support, that's all I can do:

enter image description here

<!doctype html>

<html>
    <head>
        <meta charset = "utf-8">

        <script type = "text/javascript">
            Element.prototype.getStyles = function () {
                var array = {};
                var styles = window.getComputedStyle (this, null);

                for (var i = 0; i < styles.length; i ++) {
                    var style = styles[i];

                    array[style] = styles[style];
                }

                return array; // return new Array (array, this.innerHTML); You can also return the HTMl content. I don't think its necessary
            }

            window.addEventListener ("load", function () {
                var divId = document.getElementById ("divId");
                var someClass = document.getElementsByClassName ("someClass");

                var string = "";
                var styles = divId.getStyles ();

                for (var i in styles) {
                    string += i + ": " + styles[i] + "\n";
                }

                alert (string);
                alert ("In-line style: Height ->" + styles["height"] + "\n" + "Out-line style: Width ->" + styles["width"])
                alert ("HTML: " + divId.innerHTML);

                // Same thing with the span element
            }, false);
        </script>

        <style>
            #divId {
                clear: both;
                padding: 3px;
                border: 2px dotted #CCC;
                font-size: 107%;
                line-height: 130%;
                width: 660px;
            }
            .someClass {
                color: blue;
            }
        </style>

        <title>Test</title>
    </head>

    <body>
        <div id = "divId" style = "height: 100px">
            <span class = "someClass">Some innerText</span>
        </div>
    </body>
</html>
like image 34
Caio Avatar answered Sep 22 '22 11:09

Caio