动态地将javascript插入到使用document.write的HTML中

时间:2008-09-10 12:55:44

标签: javascript html ajax

我目前正在加载一个灯箱样式弹出窗口,从XHR调用加载它的HTML。然后,使用element.innerHTML = content以“模态”弹出窗口显示此内容。这就像魅力一样。

在本网站的另一部分,我使用Flickr'徽章'(http://www.elliotswan.com/2006/08/06/custom-flickr-badge-api-documentation/)动态加载flickr图像。这样做包括一个加载flickr javascript的脚本标记,后者又会执行一些document.write个名称。

当包含在HTML中时,它们都能完美地工作。只有在灯箱中加载flickr徽章代码 时,才会呈现内容。看起来使用innerHTML来编写document.write语句已经过了一步,但我找不到任何关于此行为的javascript实现(FF2& 3,IE6& 7)的线索。

任何人都可以澄清这是否应该起作用?感谢。

7 个答案:

答案 0 :(得分:14)

通常,使用innerHTML时不会执行脚本标记。在您的情况下,这很好,因为document.write调用将消除页面中已有的所有内容。但是,这样就没有任何HTML document.write应该添加。

jQuery的HTML操作方法将为您执行HTML脚本,然后捕获对document.write的调用并将HTML放在适当的位置。如果它足够简单,那么这样的事情就可以了:

var content = '';
document.write = function(s) {
    content += s;
};
// execute the script
$('#foo').html(markupWithScriptInIt);
$('#foo .whereverTheDocumentWriteContentGoes').html(content);

虽然变得复杂。如果脚本在另一个域上,它将异步加载,因此您必须等到完成后才能获取内容。另外,如果它只是将HTML写入片段的中间而没有可以轻松选择的包装元素呢? writeCapture.js(完全披露:我写了)处理所有这些问题。我建议只使用它,但至少你可以查看代码,看看它是如何处理的。

编辑:这是一个page,展示了你想要的效果。

答案 1 :(得分:4)

我创建了一个简单的测试页面来说明问题:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <title>Document Write Testcase</title>
    </head>
    <body>
        <div id="container">
        </div>
        <div id="container2">
        </div>

        <script>
            // This doesn't work!
            var container = document.getElementById('container');
            container.innerHTML = "<script type='text/javascript'>alert('foo');document.write('bar');<\/script>";

            // This does!
            var container2 = document.getElementById('container2');
            var script = document.createElement("script");
            script.type = 'text/javascript';
            script.innerHTML = "alert('bar');document.write('foo');";
            container.appendChild(script);
        </script>
    </body>
</html>

此页面提醒'bar'并打印'foo',而我预计它也会提醒'foo'并打印'bar'。但是,遗憾的是,由于script标记是较大HTML页面的一部分,因此我无法单独标记该标记并将其附加到上面的示例中。好吧,我可以,但这需要扫描innerHTML标签的script内容,并用占位符替换它们,然后使用DOM插入它们。听起来不是 琐碎。

答案 2 :(得分:3)

使用document.writeln(content);代替document.write(content)

但是,最好的方法是使用innerHTML的串联,如下所示:

element.innerHTML += content;

将使用新内容替换旧内容的element.innerHTML = content;方法,它将覆盖元素的innerHTML!

+=中的element.innerHTML += content;运算符会在旧内容之后添加您的文字。 (就像document.write所做的那样。)

答案 3 :(得分:1)

document.write即将推出。但是,由于JavaScript的奇迹,您可以将自己的函数分配给write对象的document方法,该方法在您选择的元素上使用innerHTML来附加提供的内容

答案 4 :(得分:0)

我可以先做一些澄清,以确保我遇到问题吗?

document.write次调用会在标记的标记处向标记添加内容。例如,如果在函数中包含document.write调用但在其他地方调用该函数,则document.write输出将在标记中发生,函数定义而不是它在哪里称为

因此,要实现此功能,Flickr document.write语句将需要成为contentelement.innerHTML = content的一部分。这绝对是这样吗?

您可以通过在设置为document.write的内容中添加一个简单的innerHTML调用来快速测试这是否应该可以正常工作,并查看此操作:

<script>
  var content = "<p>1st para</p><script>document.write('<p>2nd para</p>');</script>"
  element.innerHTML = content;
</script>

如果可行,那么document.write在内容中工作的概念设置为元素的innerHTML可能会起作用。

我的直觉是它不起作用,但测试这个概念应该非常简单。

答案 5 :(得分:0)

因此,您正在使用DOM方法创建script元素并将其附加到现有元素,然后这会导致附加的script元素的内容执行?听起来不错。

您说脚本标记是较大HTML页面的一部分,因此无法单独列出。你能不给脚本标签一个ID并定位它?我可能在这里遗漏了一些明显的东西。

答案 6 :(得分:0)

理论上,是的,我可以用这种方式挑出一个脚本标签。问题是我们可能有很多情况发生,所以我试图找到这种行为的一些原因或文档。

此外,script标记在加载后似乎不再是DOM的一部分。在我们的环境中,我的container div仍然为空,因此我无法获取script标记。但它应该可以工作,因为在上面的例子中,脚本没有被执行,但仍然是DOM的一部分。