19

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");
3
  • I think your title should be "How to get all styles ..", also this is similar: stackoverflow.com/questions/754607/… Commented Jan 24, 2011 at 11:34
  • can you tell why do you need this exactly? perhaps there's an easy way of doing this. Commented Feb 3, 2011 at 12:40
  • Because I'm copying html of an element from one document to other window's document which is an iFrame. Commented Feb 7, 2011 at 20:09

9 Answers 9

13
+50

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");
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the answer. I tried what you answered. I've updated my question with the output of what I tried. Just a small change I've made to what you have answered is $(selector).get(0).outerHTML from $(selector).outerHTML() so that I don't need outerHTML.
There was one stupid err -- I've fixed it (and edited the code in my post). But then I've got another problem: security. In most browsers one cannot access CSS via DOM (i.e. the way, I use) from another domains. On stackoverflow CSS file is placed on sstatic.net/stackoverflow I've tested changed example at ibm.com/us/en/sandbox/ver2 with "#ibm-search-form" and it works, but you'll need to add var $ = jQuery; at the beginning of the function, in order to work in @ibm.com
Thanks, you will definitely get the bounty you deserve. Nicely done job. One more bug though. its missing http: when I tested as you had on the link you gave.
Note that cssText doesn't seem to include any custom styles that an element might have. Most of the time this won't be a problem, but with what I myself am working on, it's something I needed to know.
How to get the styles with Class name grouping?
|
8

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>

1 Comment

I need styles like ` <style> #divId { clear: both; padding: 3px; border: 2px dotted #CCC; font-size: 107%; line-height: 130%; width: 660px; } .someClass { color: blue; } </style>` even when they are defined in separate style sheet. And then the html mark up
7

You can get hold of a style object representing the computed style for an element using window.getComputedStyle() in most browsers and the element's currentStyle property in IE. There are several browser differences, however, with values returned for shortcut properties (such as background), color RGB values, lengths and even font-weight (see this useful test page). Test carefully.

function computedStyle(el) {
    return el.currentStyle || window.getComputedStyle(el, null);
}

alert(computedStyle(document.body).color);

1 Comment

I've updated my question just in case if it was not clear earlier.
4

You can use something like this for script:-

<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script type="text/javascript">
$(function(){
    var styleVal = $('#testDiv').attr('style');
    console.warn("styleVal >>>   " + styleVal);
})
</script>

and simple html would be like this

<div style="border:1px solid red;" id="testDiv">cfwcvb</div>

9 Comments

is console supported in other browsers? anyway +1
Console is not supported in all browsers but you can use as a substitute
What if there is a class assigned to it and that class is defined in a different css file?
Thanks, but if it doesn't support all browsers then it will not work for me.
Console is just to know the value ucan store it in a variable and use it wherever you want...
|
3

if you want to save all of the style of an element i think this will be more complicated as you think first of all my first ide was the firebug css console. this shows all fo the style of an element and i thought how? so i searched for the source code of the firebug and i found this:

http://fbug.googlecode.com/svn/branches/firebug1.7/content/firebug/css.js

this code working only on the css part.

const styleGroups =
{
    text: [
        "font-family",
        "font-size",
        "font-weight",
        "font-style",
        "color",
        "text-transform",
        "text-decoration",
        "letter-spacing",
        "word-spacing",
        "line-height",
        "text-align",
        "vertical-align",
        "direction",
        "column-count",
        "column-gap",
        "column-width"
    ],

    background: [
        "background-color",
        "background-image",
        "background-repeat",
        "background-position",
        "background-attachment",
        "opacity"
    ],

    box: [
        "width",
        "height",
        "top",
        "right",
        "bottom",
        "left",
        "margin-top",
        "margin-right",
        "margin-bottom",
        "margin-left",
        "padding-top",
        "padding-right",
        "padding-bottom",
        "padding-left",
        "border-top-width",
        "border-right-width",
        "border-bottom-width",
        "border-left-width",
        "border-top-color",
        "border-right-color",
        "border-bottom-color",
        "border-left-color",
        "border-top-style",
        "border-right-style",
        "border-bottom-style",
        "border-left-style",
        "-moz-border-top-radius",
        "-moz-border-right-radius",
        "-moz-border-bottom-radius",
        "-moz-border-left-radius",
        "outline-top-width",
        "outline-right-width",
        "outline-bottom-width",
        "outline-left-width",
        "outline-top-color",
        "outline-right-color",
        "outline-bottom-color",
        "outline-left-color",
        "outline-top-style",
        "outline-right-style",
        "outline-bottom-style",
        "outline-left-style"
    ],

    layout: [
        "position",
        "display",
        "visibility",
        "z-index",
        "overflow-x",  // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow
        "overflow-y",
        "overflow-clip",
        "white-space",
        "clip",
        "float",
        "clear",
        "-moz-box-sizing"
    ],

    other: [
        "cursor",
        "list-style-image",
        "list-style-position",
        "list-style-type",
        "marker-offset",
        "user-focus",
        "user-select",
        "user-modify",
        "user-input"
    ]
};

the function which gets all of the styles.

updateComputedView: function(element)
{
    var win = element.ownerDocument.defaultView;
    var style = win.getComputedStyle(element, "");

    var groups = [];

    for (var groupName in styleGroups)
    {
        var title = $STR("StyleGroup-" + groupName);
        var group = {title: title, props: []};
        groups.push(group);

        var props = styleGroups[groupName];
        for (var i = 0; i < props.length; ++i)
        {
            var propName = props[i];
            var propValue = stripUnits(rgbToHex(style.getPropertyValue(propName)));
            if (propValue)
                group.props.push({name: propName, value: propValue});
        }
    }

    var result = this.template.computedTag.replace({groups: groups}, this.panelNode);
    dispatch(this.fbListeners, 'onCSSRulesAdded', [this, result]);
}

function stripUnits(value)
{
    // remove units from '0px', '0em' etc. leave non-zero units in-tact.
    return value.replace(/(url\(.*?\)|[^0]\S*\s*)|0(%|em|ex|px|in|cm|mm|pt|pc)(\s|$)/gi, function(_, skip, remove, whitespace) {
    return skip || ('0' + whitespace);
    });
}

in this code i figured out that the

win.getComputedStyle(element, "")

to get all of the styles of an element, and then with a for loop gets all of the style and prints out. so i think the getComputedSTyle is the main function to use, and after this you can get the props one by one with:

style.getPropertyValue(propName)

Comments

1

Based on kirilloid's answer, I've created a developer tools extension for Chrome that incorporates that code for capturing styles and markup for a page fragment. The extension is in the Chrome Web Store and is on Github. All of the "Author Styles" output options use that method for iterating over the stylesheets.

enter image description here

Comments

0

The .css() method gets a particular style of the element... I don't know if you can retrieve all styles:

http://api.jquery.com/css/

Comments

0

Generally you can access style parameter using .attr('style'). If you want to access computed style you can use window.getComputedStyle(element) in Opera, Firefox, Chrome and other sane browsers. For IE you'd do the same with element.currentStyle.

Also if you wish to access individual CSS style you can do so with jQuery .css method. Like so $("#divId").css('font-size').

Comments

0

You can get the stylesheet defined inside style tags under document.styleSheets. You can read the rules into a map, and find them by selectorText. So by id: "#id", by classes: ".className". By safari or chrome you can use getMatchedCSSRules.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.