从包含Div和Script标记的HTML编码字符串动态添加div元素

4

我有一个用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>

我在这里做错了什么?


你不是忘了分号了吗? - Abhi
我曾经尝试过,但那并没有解决我的问题。 - mike01010
你不能直接在页面上包含d3js吗?我是指像jQuery一样添加<script src="http://d3js.org/d3.v3.min.js"></script>这部分。 - Himal
我更喜欢让被注入页面的div元素知道它所有的引用/包含,而不是让页面“所有者”进行修改以支持我的代码片段。 - mike01010
$(decoded).appendTo("#parentDiv"); - Teo
@Teo - 对我不起作用。仍然需要在我尝试创建的div之外添加d3包含才能使其正常工作。 - mike01010
6个回答

5

一旦您将元素附加到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;
};

这个函数将返回一个脚本数组。通过筛选数组,直到找到你想要的脚本,然后使用eval函数执行它。

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

3
或者简单地使用 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 + "!"; });
});

2
问题在于您在加载d3js文件之前执行了d3.js代码。您可能需要查看jQuery.getScript等内容。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>

0

尝试在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>


0
我尝试了下面的方法,它起作用了。我将您的代码转换为一个函数,在这个函数中,您首先呈现脚本,然后调用该函数。
<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>

0
脚本正在异步加载,这意味着d3.v3.min.js中的函数和变量在下面的JavaScript执行之前不存在。标准的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);

希望这能有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接