Including rendering of an HTML document in another HTML document

I have a line representing a stand-alone (and valid XHTML 1.0 Strict) HTML document, something like

var html = "<?xml ... <!DOCTYPE ... <html><head><style>...</style></head> <body><table>...</table></body></html>"; 

The body of this HTML document contains a table with the CSS style described in the header of the HTML document.

I also have a DOM tree for another HTML document. How can I include in this DOM tree the DOM tree of the table with the correct style (as described in the HTML line)?

I am particularly interested in jQuery based solution.

EDIT . To be more specific, the example HTML string I'm talking about is embedded in this XML document .

+4
source share
6 answers

I may be missing a point, but why not load a line into an IFRAME for rendering - this solves all the problems with having two separate DOM trees and two separate CSS rule sets.

This code will do this:

 $(function() { var $frame = $('<iframe style="width:200px; height:100px; border: 0px;">'); $('body').html( $frame ); setTimeout( function() { var doc = $frame[0].contentWindow.document; var $body = $('body',doc); $body.html(your_html); }, 1 ); }); 

(which I shot here: putting html inside an iframe (using javascript) )

Then, if you are worried about the size of the iframe, you can set it with:

 $frame[0].style.height = $frame[0].contentWindow.document.body.offsetHeight + 'px'; $frame[0].style.width = $frame[0].contentWindow.document.body.offsetWidth + 'px'; 
+14
source

It makes no sense to have two full DOM trees on the same page, so you want to extract what you want from them and use them only.

Convert the string to a jQuery object and parse what you need:

 var html = "<html><head><style>...</style></head> <body><table>...</table></body></html>"; // Not sure if you are a trying to merge to DOMs together or just // trying to place what you want on the page so, I'm going to go // with the former as it may be more tricky. var other_html = "<html><head><style>...</style></head> <body><!-- some stuff --></body></html>"; var jq_html = $(html); var jq_other_html = $(other_html); var style = jq_html.find('head').find('style'); var table_and_stuff = jq_html.find('body').html(); jq_other_html.find('head').append(style).end().append(table_and_stuff); 

It should be possible. CSS should be automatically recognized by the browser after it is inserted into the page.

NOTE.
To ensure that the new CSS stylesheet adds only new styles and does not override your current (s), you must add the sheet to the main tag and not add it. So the last line should be like this:

 jq_other_html.find('head').prepend(style).end().append(table_and_stuff); 
+3
source

Instead of improving my other answer, I would rather create a new one, since I basically need to rewrite it to work the way you want, and the old answer may help people for other reasons ...

So, after extracting the HTML string from the XML associated with you, you can continue it as follows:

 // First we'll extract out the parts of the HTML-string that we need. var jq_html = $(html_from_xml); var style = jq_html.find('head').find('style').html(); var style_string = style.toString(); var table_and_stuff = jq_html.find('body').html(); // If you want to place it into the existing page DOM, // we need to place it inside a new DIV with a known ID... $('body').append('<div id="new_stuff"></div>'); $('#new_stuff').html(table_and_stuff); // Now, we need to re-write the styles so that they only // affect the content of the 'new_stuff' DIV: styles_array = style_string.split('}'); var new_styles = ''; $.each(styles_array,function(i) { if(i<(styles_array.length-1)) { new_styles += "#new_stuff "+styles_array[i]+"}"; } }) $('head').append('<style type="text/css">'+new_styles+'</style>'); 

And it really should be. The trick is that CSS will choose the most specific style for this case. So, if you have a <td> inside the div "newstuff", it will get the style from the new stylesheet. If you have a <td> outside of this div "newstuff", it will get the old style.

Hope this solves your problem.

+1
source

Paste it into the built-in frame.

Using the question I asked earlier , I have a solution like this:

First you have an iframe, with some id

 <iframe id="preview" src="/empty.html"></iframe> 

Then do the style:

 iframe#preview { margin: 30px 10px; width: 90%; height: 800px; } 

And here is the function to insert html text into this frame (uses jquery)

 function preview( html ) { var doc = $("#preview")[0].contentWindow.document var body = $('body',doc) body.html( html ); } 

I used this to successfully display html content, including any inline css that it might include.

+1
source

Here is my code that does what you described. Two things to note

  • For some reason, find () didn't work on the fly that I got from the jquery object, maybe someone can find out what I'm doing wrong there.
  • I added this new dom for the body element for illustration. You can just add it to your second home

  var insertStr = "your string here"; var newDom = $(insertStr); // getting [meta style table.drs] // I had to use the array as newDom.find would not work for me which I was expecting would work var styleText = $(newDom[1]).text(); var tableElm = $(newDom[2]); $(newDom[2]).appendTo('body'); var selectors = styleText.split(/{[\s\w\.\(\)':;"#%=/-]*}/); var styles = styleText.match(/{[\s\w\.\(\)':;"#%=/-]*}/g); for ( var i =0; i < styles.length; i++ ) { var style = styles[i]; style = style.replace("{",""); style = style.replace("}",""); if ( selectors[i].indexOf("table.drs") > -1 ) { // identify top-level elm // apply to self tableElm.attr('style',style); } else { // apply to its children tableElm.find(selectors[i]).attr('style',style); } 

}

+1
source

Here is some test code that demonstrates how I will do this. The code extracts the <style> element from the passed HTML and adds a custom identifier to all selectors, and then injects the HTML into the <div> with that identifier. This way, all CSS transmitted by HTML will only apply to the nested table:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Untitled Document</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function() { var html = '<?xml version="1.0" encoding="UTF-8"?>\n\ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\ <html xmlns="http://www.w3.org/1999/xhtml">\n\ <head>\n\ <title></title>\n\ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>\n\ <style type="text/css">\n\ div.dom { background-color: #ace; margin-bottom: 0.5em } table.drs { font-family: monospace; padding: 0.4em 0.4em 0.4em 0.4em; border: 1px solid black; margin-bottom: 2em; background-color: #eee; border-collapse: collapse }\n\ td { vertical-align: top; padding: 0.3em 0.3em 0.3em 0.3em; border: 1px solid black }\n\ td.op { vertical-align: middle; font-size: 110%; border: none }\n\ </style>\n\ </head>\n\ <body><table class="drs"><tr><td><div class="dom">[]</div></td></tr></table></body>\n\ </html>'; var style = html.match(/<style([^>]*)>([^<]*)<\/style>/); var modifiedStyle = style[2].replace(/\s*(} |^|\n)\s*([^{]+)/g, " $1 #inserthere $2"); $(document).find('head').prepend("<style" + style[1] + ">" + modifiedStyle + "</style"); $("#inserthere").append($(html).children()); }); </script> </head> <body> <div id="inserthere"> </div> </body> </html> 

Obviously, you will have to change this for your situation, but this is the starting point.

0
source

All Articles