繁体   English   中英

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

[英]Including the rendering of an HTML document into another HTML document

我有一个字符串代表一个独立的(和有效的XHTML 1.0 Strict)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字符串的一个例子嵌入到这个XML文档中

我可能会忽略这一点,但为什么不将字符串加载到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 );
});

(我从这里解除了: 将html放在iframe中(使用javascript)

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

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

在同一页面上拥有两个完整的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样式表只添加新的风格,而不是覆盖当前的一个(或多个),你必须在前面加上纸张的头部标记,而不是其追加 所以,最后一行需要像这样:

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

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

因此,从您链接到的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> ,它将从新样式表中获得样式。 如果你在<td> newstuff“div之外有一个<td> ,它将获得旧式。

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

将其插入内联框架。

使用我之前提到问题 ,我有一个这样的解决方案:

首先,有一个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。

这是我的代码,你做了你描述的。 有两点需要注意

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

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

   }

}

这是一些测试代码,演示了我是如何做到这一点的。 代码从传递的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>

显然你必须根据你的情况修改它,但这是一个起点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM