在教程中,我学会了使用document.write
. 现在我明白了,许多人对此不以为然。我试过print()
了,但它确实将它发送到打印机。
那么我应该使用哪些替代品,为什么不应该使用document.write
呢?w3schools 和 MDN 都使用document.write
.
在教程中,我学会了使用document.write
. 现在我明白了,许多人对此不以为然。我试过print()
了,但它确实将它发送到打印机。
那么我应该使用哪些替代品,为什么不应该使用document.write
呢?w3schools 和 MDN 都使用document.write
.
您的 HTML 被替换的原因是因为一个邪恶的 JavaScript 函数:document.write()
.
这绝对是“糟糕的形式”。如果您在页面加载时使用它,它仅适用于网页;如果您在运行时使用它,它将用输入替换您的整个文档。如果你将它作为严格的 XHTML 结构应用,它甚至不是有效的代码。
document.write
写入文档流。调用document.write
已关闭(或加载)的文档会自动调用document.open
这将清除文档。
——引用自 MDN
document.write()
有两个心腹document.open()
, 和document.close()
。加载 HTML 文档时,该文档是“打开的”。 当文档完成加载时,文档已“关闭”。此时使用document.write()
将删除您的整个(关闭的)HTML 文档并将其替换为新的(打开的)文档。这意味着您的网页已自行擦除并开始编写新页面 - 从头开始。
我相信document.write()
也会导致浏览器性能下降(如果我错了,请纠正我)。
此示例在页面加载后将输出写入 HTML 文档。当您按下“消灭”按钮时, Watchdocument.write()
的邪恶力量会清除整个文档:
I am an ordinary HTML page. I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.write('This HTML page has been succesfully exterminated.')" value="exterminate"/>
me!
.innerHTML
这是一个很好的选择,但是这个属性必须附加到你想要放置文本的元素上。 例子:document.getElementById('output1').innerHTML = 'Some text!';
.createTextNode()
是W3C推荐的替代方案。 例子:var para = document.createElement('p');
para.appendChild(document.createTextNode('Hello, '));
注意:已知这会降低一些性能(比 慢.innerHTML
)。我建议.innerHTML
改用。
.innerHTML
:I am an ordinary HTML page.
I am innocent, and purely for informational purposes.
Please do not
<input type="button" onclick="document.getElementById('output1').innerHTML = 'There was an error exterminating this page. Please replace <code>.innerHTML</code> with <code>document.write()</code> to complete extermination.';" value="exterminate"/>
me!
<p id="output1"></p>
这是应该就地替换 document.write 的代码:
document.write=function(s){
var scripts = document.getElementsByTagName('script');
var lastScript = scripts[scripts.length-1];
lastScript.insertAdjacentHTML("beforebegin", s);
}
您可以结合insertAdjacentHTML方法和document.currentScript属性。
Element 接口的insertAdjacentHTML()
方法将指定的文本解析为 HTML 或 XML,并将生成的节点插入到 DOM 树中的指定位置:
'beforebegin'
: 在元素本身之前。'afterbegin'
: 就在元素内部,在它的第一个子元素之前。'beforeend'
: 就在元素内部,在它的最后一个子元素之后。'afterend'
: 在元素本身之后。该document.currentScript
属性返回<script>
当前正在处理其脚本的元素。最佳位置是beforebegin — 新的 HTML 将插入到<script>
它自己之前。为了匹配document.write
的本机行为,可以将文本放置在end 之后,但是随后对函数的连续调用中的节点不会按照您调用它们的顺序(就像document.write
那样)放置,而是相反。HTML 出现的顺序可能比它们相对于<script>
标签的位置更重要,因此使用beforebegin。
document.currentScript.insertAdjacentHTML(
'beforebegin',
'This is a document.write alternative'
)
作为推荐的替代方法,document.write
您可以使用DOM 操作直接查询节点元素并将其添加到 DOM。
我看不到document.write
. 例如,如果您在onload
事件触发之前使用它来从结构化数据构建元素,那么它就是合适的工具。insertAdjacentHTML
在构建 DOM 之后使用或显式添加节点到 DOM 没有性能优势。我刚刚使用一个旧脚本以三种不同的方式对其进行了测试,该脚本曾经用于为一组 4 个调制解调器上的 24/7 服务安排传入的调制解调器呼叫。
到它完成时,这个脚本创建了超过 3000 个 DOM 节点,主要是表格单元格。在一台运行 Firefox 的 7 年旧 PC 上的 Vista 上,这个小练习只用了不到 2 秒的时间,使用document.write
了一个本地 12kb 源文件和三个 1px 的 GIF,这些 GIF 被重复使用了大约 2000 次。该页面刚刚完全形成,准备好处理事件。
使用insertAdjacentHTML
不是直接替代品,因为浏览器会关闭脚本需要保持打开状态的标签,并且最终创建一个损坏的页面需要两倍的时间。将所有部分写入一个字符串,然后将其传递给它insertAdjacentHTML
需要更长的时间,但至少你得到了设计的页面。其他选项(比如一次手动重新构建一个节点的 DOM)太荒谬了,我什至不会去那里。
有时document.write
是要使用的东西。它是 JavaScript 中最古老的方法之一这一事实并不是反对它,而是有利于它的一点——它是高度优化的代码,它完全按照它的意图去做,并且从一开始就一直在做。
很高兴知道有其他可用的后加载方法,但必须理解这些完全是为了不同的目的;即在创建 DOM 并为其分配内存之后对其进行修改。如果您的脚本旨在编写浏览器首先从中创建 DOM 的 HTML,则使用这些方法本质上会占用更多资源。
只需编写它,让浏览器和解释器完成工作。这就是他们的目的。
PS:我刚刚onload
在标签中使用了一个参数进行了测试,即使在这一点上,body
文档仍然可以按预期运行。此外,在最新版本的 Firefox 中,各种方法之间没有明显的性能差异。当然,硬件/软件堆栈中的某个地方可能会进行大量缓存,但这才是真正的重点——让机器来完成工作。不过,它可能会对便宜的智能手机产生影响。干杯!open
document.write()
这个问题取决于你实际上想要做什么。
通常,document.write
您可以使用someElement.innerHTML
或更好地document.createElement
使用someElement.appendChild
.
您还可以考虑使用像 jQuery 这样的库并使用其中的修改函数:http ://api.jquery.com/category/manipulation/
这可能是最正确、最直接的替换:insertAdjacentHTML。
尝试使用 getElementById() 或 getElementsByName() 来访问特定元素,然后使用 innerHTML 属性:
<html>
<body>
<div id="myDiv1"></div>
<div id="myDiv2"></div>
</body>
<script type="text/javascript">
var myDiv1 = document.getElementById("myDiv1");
var myDiv2 = document.getElementById("myDiv2");
myDiv1.innerHTML = "<b>Content of 1st DIV</b>";
myDiv2.innerHTML = "<i>Content of second DIV element</i>";
</script>
</html>
采用
var documentwrite =(value, method="", display="")=>{
switch(display) {
case "block":
var x = document.createElement("p");
break;
case "inline":
var x = document.createElement("span");
break;
default:
var x = document.createElement("p");
}
var t = document.createTextNode(value);
x.appendChild(t);
if(method==""){
document.body.appendChild(x);
}
else{
document.querySelector(method).appendChild(x);
}
}
并根据您的要求调用该函数,如下所示
documentwrite("My sample text"); //print value inside body
documentwrite("My sample text inside id", "#demoid", "block"); // print value inside id and display block
documentwrite("My sample text inside class", ".democlass","inline"); // print value inside class and and display inline
我不确定这是否会完全有效,但我想到了
var docwrite = function(doc) {
document.write(doc);
};
这为我解决了错误消息的问题。