1

I am trying to create a general function that will extract a div content (with nested elements) and save it locally in an HTML file.

Basically I get the div innerHTML, wrap it in html/head/body tags and then save it:

function div2html() {
    var inner=document.getElementById("div2save").innerHTML;
    var html="<html><head></head><body>"+inner+"</body></html>";
    saveTextAsFile("div2html.html", html);
}

See a working version here: jsfiddle

However I am not sure how to handle classes. As you can see the class in the sample (bigbold) is not embedded in the new HTML. I need some way to get all the classes used in the div and then add them (or the computed styles ?) to the html I generate .. is this possible ? is there any other way around it ?

kofifus
  • 17,260
  • 17
  • 99
  • 173

3 Answers3

2

Try including style element .outerHTML within saved html

function div2html() {
    var inner=document.getElementById("div2save").innerHTML;
    var style = document.getElementsByTagName("style")[0].outerHTML;
    var html="<html><head>"+style+"</head><body>"+inner+"</body></html>";
    saveTextAsFile("div2html.html", html);
}

jsfiddle http://jsfiddle.net/fb6s763w/1/


Alternatively, using window.getComputedStyle() to select only css of #div2save child node

function div2html() {
    var inner = document.getElementById("div2save");
    var style = window.getComputedStyle(inner.children[0]).cssText;
    var html = "<html><head><style>" 
               + "." + inner.children[0].className 
               + "{" + style + "}" 
               + "</style></head><body>" 
               + inner.innerHTML + "</body></html>";
    saveTextAsFile("div2html.html", html);
}

jsfiddle http://jsfiddle.net/fb6s763w/2/

guest271314
  • 1
  • 15
  • 104
  • 177
  • This is really good ! and I will prob mark this as the answer if nothing better comes. The only problem is that it gets ALL css into the new HTML and not just the one used in the div to be saved, which in the project I'm working it will produce a lot of unnecessary html. – kofifus Oct 07 '15 at 03:06
  • @kofifus See updated post ; included alternative approach , using `window.getComputedStyle()` to select , save only `css` of `#div2save` child node – guest271314 Oct 07 '15 at 03:14
  • Thank you ! this secod solution will not work for nested elements etc ... see http://jsfiddle.net/fb6s763w/3/ .. is it possible to account for that ? – kofifus Oct 07 '15 at 03:44
  • @kofifus _"nested elements"_ not appear at original Question ? Tried using loop on children of `#div2save` to extract `cssText` of each child element ? – guest271314 Oct 07 '15 at 04:02
  • true, I thought it was obvious ..I edited my question thx! ... simply looping is not so easy because I need to make sure not to add classes twice. I'll give it a try. – kofifus Oct 07 '15 at 05:56
0

Looks like this might be able to help you out: https://github.com/Automattic/juice

Jephron
  • 2,652
  • 1
  • 23
  • 34
0

If the CSS of the page is not big, a simple solution is to include it all in the saved html as suggested by guest271314 above with

var style = document.getElementsByTagName("style")[0].outerHTML;

see jsfiddle

A more comprehensive solution extracts the classes from the div and then adds only the rules of those classes to the div (Using code from How do you read CSS rule values with JavaScript?)

function div2html(divId) {
    var html = document.getElementById(divId).innerHTML;

    // get all css classes in html
    var cssClasses = [];
    var classRegexp = /class=['"](.*?)['"]/g;
    var m;
    while ((m = classRegexp.exec(html))) cssClasses = cssClasses.concat(cssClasses, m[1].split(" "));

    // filter non unique or empty cssClasses
    cssClasses = cssClasses.filter(function (item, pos, self) {
        return item && self.indexOf(item) == pos;
    });

    // get html of classes
    var cssHtml = '';
    for (var i = 0; i < cssClasses.length; i++) cssHtml += getRule('.' + cssClasses[i]);

    // assemble html
    var html = "<html><head><style>" + cssHtml + "</style></head><body>" + html + "</body></html>";
    console.log(html);
    saveTextAsFile("div2html.html", html);
}

see jsfiddle

Community
  • 1
  • 1
kofifus
  • 17,260
  • 17
  • 99
  • 173