包括将HTML文档呈现到另一个HTML文档中

时间:2009-04-15 17:03:48

标签: javascript jquery html css

我有一个表示独立(和有效的XHTML 1.0严格)HTML文档的字符串,类似于

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

此HTML文档的正文包含一个CSS样式的表 在HTML文档的头部描述。

我还有另一个HTML文档的DOM树。 我如何在这个DOM树中包含具有正确样式的表的DOM树(如HTML字符串中所述)?

我对基于jQuery的解决方案特别感兴趣。

编辑:更具体一点,我正在谈论的HTML字符串示例 嵌入this XML-document

6 个答案:

答案 0 :(得分:14)

我可能会错过这一点,但为什么不将字符串加载到IFRAME中进行渲染 - 这解决了我拥有两个独立DOM树和两组独立CSS规则的所有问题。

此代码将执行此操作:

$(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 );
});

(我从这里解除了:putting html inside an iframe (using javascript)

然后,如果您担心IFRAME的大小,可以使用以下命令设置:

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

答案 1 :(得分:3)

在同一页面上拥有两个完整的DOM树是没有意义的,因此您需要提取您想要的内容并仅使用它。

将字符串转换为jQuery对象并解析出您需要的内容,如下所示:

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);

应该这样做。浏览器插入页面后,CSS应自动识别。

注意:
要使新的CSS样式表仅添加新样式而不覆盖当前样式,您必须表单添加到head标记中,而不是追加它。所以,最后一行必须是这样的:

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

答案 2 :(得分:1)

我宁愿做一个新的答案,而不是改进我的另一个答案,因为我基本上需要重新编写它以便按照你想要的方式工作而旧答案可能会因其他原因帮助人们......

因此,在从您链接的XML中提取出HTML字符串后,您可以像这样:

// 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's 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>');

这应该真的这样做。诀窍是CSS将为案例选择最具体的风格。所以,如果你在“newstuff”div中有<td>,它将从新样式表中获得样式。如果你在“newstuff”div之外有一个<td>,它将获得旧样式。

我希望这能解决你的问题。

答案 3 :(得分:1)

将其插入内嵌框架。

使用question I asked earlier,我有一个这样的解决方案:

首先,有一个iframe,有一些id

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

然后设计它:

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

这是一个将html文本插入到该框架中的函数(使用jquery)

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

我用它来成功渲染html的内容,包括它可能包含的任何嵌入式CSS。

答案 4 :(得分:1)

这是我执行您所描述内容的代码。 有两点需要注意

  1. 由于某种原因,find()没有对我从jquery对象获得的'on-the-fly'dom工作,可能有人可以找出我做错了什么
  2. 为了说明的目的,我将这个新的dom附加到'body'元素。您可以轻松地将它附加到您的第二个dom

  3.    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);
    
       }
    

    }

答案 5 :(得分:0)

这是一些测试代码,展示了我是如何做到这一点的。代码从传递的HTML中提取<style>元素,并向所有选择器添加自定义ID,然后将HTML注入具有该ID的<div>。这样,HTML传递的所有CSS都只适用于注入的表:

<!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>

显然你必须根据自己的情况对其进行修改,但这是一个起点。