从包含 Div 和脚本标记的 html 编码字符串中动态添加 div 元素

Posted

技术标签:

【中文标题】从包含 Div 和脚本标记的 html 编码字符串中动态添加 div 元素【英文标题】:Dynamically adding div element from html encoded string containing Div and Script markup 【发布时间】:2014-11-09 16:09:43 【问题描述】:

我有一个 python 应用程序,它可以将 html 作为 json 有效负载的一部分传递到页面。我在该页面中尝试做的是解码 html 并将其动态添加到 DOM。 html 标记用于带有子脚本元素的 Div 元素。这是我的代码,它可以很好地打印出解码后的 HTML,但实际上并没有执行脚本:

<div  id="parentDiv">
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script type='text/javascript'>
        var child_div = "&lt;div id=&#39;testDiv&#39;&gt;\n &lt;script src=&quot;http://d3js.org/d3.v3.min.js&quot;&gt;&lt;/script&gt;\n &lt;script&gt;\n d3.select(&quot;#testDiv&quot;) \n .data([4, 8, 15, 16, 23, 42])\n .enter().append(&quot;p&quot;)\n .text(function(d)  return &quot;I'm number &quot; + d + &quot;!&quot;;\n );\n &lt;/script&gt;\n &lt;/div&gt;";
        decoded = $('<div />').html(child_div).text();
        console.log(decoded);
        $("#parentDiv").append(decoded);
    </script>
</div>

但是,如果我使用上面代码中记录的 html 并从中创建一个页面,它可以正常执行脚本。这是解码后的 html 的样子,也是我希望动态添加到父 div 的内容:

   <div  id="parentDiv">
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <div id='testDiv'>
       <script src="http://d3js.org/d3.v3.min.js"></script>
       <script>
           d3.select("#testDiv")
          .data([4, 8, 15, 16, 23, 42])
          .enter().append("p")
          .text(function(d)  return "I'm number " + d + "!"; );
       </script>
    </div>
</div>

我在这里做错了什么?

【问题讨论】:

你是不是少了一个分号?? 我是,但这并不能解决我的问题。 你不能直接在页面上包含 d3js 吗?补充:我的意思是&lt;script src="http://d3js.org/d3.v3.min.js"&gt;&lt;/script&gt; part.just like jQuery 我宁愿保持这样,被注入页面的 div 元素知道它的所有引用/包含,而不是让页面“所有者”必须进行修改以支持我的 sn-p。 $(decoded).appendTo("#parentDiv"); 【参考方案1】:

添加元素后,执行 DOM,它们确实存在于 DOM 中,但脚本尚未初始化。

您可以通过以下方式访问脚本标签:

function getScriptsAsText() 
    var div = document.createElement('div');
    var scripts = [];
    var scriptNodes = document.getElementsByTagName('script');

    for (var i = 0, iLen = scriptNodes.length; i < iLen; i++) 
        div.appendChild(scriptNodes[i].cloneNode(true));
        scripts.push(div.innerHTML);
        div.removeChild(div.firstChild);
    
    return scripts;
;

此函数将返回数组中的脚本。 过滤数组,直到找到您所追求的脚本,然后对其进行评估。

var scripts = getScriptsAsText();
eval(scripts[0])

【讨论】:

【参考方案2】:

或者简单的你可以使用http://www.dustindiaz.com/scriptjs :) 简单

$script('http://d3js.org/d3.v3.min.js', function()
   d3.select("#testDiv")
          .data([4, 8, 15, 16, 23, 42])
          .enter().append("p")
          .text(function(d)  return "I'm number " + d + "!"; );
);

【讨论】:

【参考方案3】:

问题是您在加载 d3js 文件之前正在执行 d3.js 代码。您可能想查看jQuery.getScript

类似的,

$.getScript('http://d3js.org/d3.v3.min.js', function()

  //d3.js stuff here

);

添加:

此外,您当前的脚本可能甚至不会加载 d3.js 文件。您必须使用类似的东西,

<script>

 var scref=document.createElement('script');

 scref.setAttribute("type","text/javascript")

 scref.setAttribute("src", 'http://d3js.org/d3.v3.min.js');

 document.getElementById("parentDiv").appendChild(scref);

</script>

【讨论】:

【参考方案4】:

脚本正在异步加载,这实质上意味着它下面的 JavaScript 在 d3.v3.min.js 中的函数和变量存在之前执行。标准 JQuery 包含一个名为 $.getScript() 的函数,该函数在指定为第一个参数的依赖项完成加载之前阻止脚本的执行。 您必须将服务器生成的代码更改为如下所示:

<div id='testDiv'>
<script>
$.getScript('http://d3js.org/d3.v3.min.js', function()
    d3.select("#testDiv") 
    .data([4, 8, 15, 16, 23, 42])
    .enter().append("p")
    .text(function(d) 
        return "I'm number " + d + "!";
    );
);
</script>
</div>

最后根据您的示例,使用以下命令执行它:

var child_div = **ABOVE MENTIONED ENCODED VERSION**;
var decoded = $('<div />').html(child_div).text();
$("#parentDiv").append(decoded);

希望对你有帮助

【讨论】:

【参考方案5】:

试着在 OP 调整一块

<div  id="parentDiv">
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <!-- added 
         `<script src="http://d3js.org/d3.v3.min.js"></script>`
    -->
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script type='text/javascript'>
    // removed
    // `&lt;script src=&quot;http://d3js.org/d3.v3.min.js&quot;&gt;&lt;/script&gt;\n`
        var child_div = "&lt;div id=&#39;testDiv&#39;&gt;\n &lt;script&gt;\n d3.select(&quot;#testDiv&quot;) \n .data([4, 8, 15, 16, 23, 42])\n .enter().append(&quot;p&quot;)\n .text(function(d)  return &quot;I'm number &quot; + d + &quot;!&quot;;\n );\n &lt;/script&gt;\n &lt;/div&gt;";
        decoded = $('<div />').html(child_div).text();
        console.log(decoded);
        $("#parentDiv").append(decoded);
    </script>
</div>

【讨论】:

【参考方案6】:

我尝试了以下方法,它奏效了。我将您的代码转换为一个函数,您首先渲染脚本,然后调用该函数。

<html><head></head><body>

<div id="parentDiv">

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script type='text/javascript'>
        function f1() 
            var child_div = "&lt;div id=&#39;testDiv&#39;&gt;\n &lt;script src=&quot;http://d3js.org/d3.v3.min.js&quot;&gt;&lt;/script&gt;\n &lt;script&gt;\n d3.select(&quot;#testDiv&quot;) \n .data([4, 8, 15, 16, 23, 42])\n .enter().append(&quot;p&quot;)\n .text(function(d)  return &quot;I'm number &quot; + d + &quot;!&quot;;\n );\n &lt;/script&gt;\n &lt;/div&gt;";
            decoded = $('<div />').html(child_div).text();
            alert(decoded);

            console.log(decoded);
            $("#parentDiv").append(decoded);
        

        f1();
    </script>
</div></body></html>

【讨论】:

以上是关于从包含 Div 和脚本标记的 html 编码字符串中动态添加 div 元素的主要内容,如果未能解决你的问题,请参考以下文章

从包含在 HTML 标记和不带标记的字符串中的一系列字符串中提取文本

ELECTRON - 加载包含脚本标签的本地 HTML 文件

需要 php 编码特殊字符而不是 html 标签,以便包含在 wordpress 扩展 rss 文件中

HTML 编码问题 - 显示“”字符而不是“ ”

从 HTML div 中删除所有文本内容,但保留 HTML 标记和结构

Struts2标记中的HTML标记