代码之家  ›  专栏  ›  技术社区  ›  Kaarel

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

  •  4
  • Kaarel  · 技术社区  · 15 年前

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

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

    此HTML文档的正文包含一个其CSS样式的表 在HTML文档的标题中描述。

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

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

    编辑 :更具体地说,是我正在讨论的HTML字符串的一个示例 嵌入到 this XML-document .

    6 回复  |  直到 15 年前
        1
  •  14
  •   Community Paul Sweatte    7 年前

    我可能错过了这一点,但为什么不将字符串加载到一个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';
    
        2
  •  3
  •   KyleFarris    15 年前

    在同一个页面上有两个完整的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);
    
        3
  •  1
  •   KyleFarris    15 年前

    我不想改进我的另一个答案,我宁愿做一个新的,因为我基本上需要重新写它来满足你的需要,而旧的答案可能会因为其他原因帮助人们……

    因此,在从链接到的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将为案例选择最具体的样式。所以,如果你有 <td> 在“newstuf”分区中,它将从新样式表中获取样式。如果你有 <TD & GT; 除了那个“Newstuff”分区,它将得到旧的风格。

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

        4
  •  1
  •   Community Paul Sweatte    7 年前

    将其插入一个内嵌框架。

    使用A 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。

        5
  •  1
  •   Amit    15 年前

    这是我的代码,按照您的描述执行。 需要注意的两件事

    1. 出于某种原因,find()不能在jquery对象中得到的“动态”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);
    
       }
    

    }

        6
  •  0
  •   inxilpro    15 年前

    下面是一些测试代码,演示了我如何做到这一点。代码提取了 <style> 元素,并将自定义ID添加到所有选择器中,然后将HTML注入到 <div> 使用该ID。这样,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>
    

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