18

我目前正在加载一个灯箱样式的弹出窗口,它从 XHR 调用中加载它的 HTML。element.innerHTML = content然后使用This works like a charm将这些内容显示在“模态”弹出窗口中。

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

当包含在 HTML 中时,它们都可以完美地工作。仅当在灯箱内加载 flickr 徽章代码时,根本不会呈现任何内容。似乎使用innerHTMLto write document.writestatements 走得太远了,但我在这种行为的 javascript 实现(FF2&3,IE6&7)中找不到任何线索。

谁能澄清这是否应该或不应该工作?谢谢。

4

7 回答 7

15

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

jQuery 的 HTML 操作方法将为您执行 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 (完全披露:我写的)处理所有这些问题。我建议只使用它,但至少您可以查看代码以了解它如何处理所有内容。

编辑:这是一个页面,展示了您想要的效果。

于 2009-12-07T22:16:56.530 回答
5

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

<!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 插入它们。听起来不是那么微不足道。

于 2008-09-10T13:25:31.743 回答
4

使用document.writeln(content);而不是document.write(content).

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

element.innerHTML += content;

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

而使用+=运算符 inelement.innerHTML += content会将您的文本附加到旧内容之后。(类似于做什么document.write。)

于 2011-08-24T12:12:58.623 回答
1

document.write就像它们来时一样被弃用。不过,由于 JavaScript 的奇妙之处,您可以将自己的函数分配给对象的write方法,该方法在您选择的元素上使用,以附加提供的内容。documentinnerHTML

于 2008-09-10T14:03:25.193 回答
0

我可以先得到一些澄清以确保我得到了问题吗?

document.write调用将在它们发生的标记点处将内容添加到标记中。例如,如果您document.write在函数中包含调用但在其他地方调用该函数,则document.write输出将发生在标记中定义该函数的位置而不是调用它的位置。

因此,要使其在所有 Flickrdocument.write语句中起作用,需要成为contentin 的一部分element.innerHTML = content。肯定是这样吗?

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

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

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

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

于 2008-09-10T13:13:20.727 回答
0

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

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

于 2008-09-10T13:48:57.363 回答
0

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

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

于 2008-09-10T13:59:58.447 回答