函数调用中的 document.write 和 innerHTML
Posted
技术标签:
【中文标题】函数调用中的 document.write 和 innerHTML【英文标题】:document.write and innerHTML in function call 【发布时间】:2012-05-23 00:43:22 【问题描述】:我是 javascript 的新手,我想知道为什么在这个脚本中 document.write
工作得很好,而 innerhtml 却不行(我在正文中给出了一个 div id 计时器)。是不是innerHTML 需要在html 的正文部分发生Onload 事件?如果是,为什么? (我在html文档的head部分调用函数writehere()
。
<script language="javascript">
function writehere()
document.write("hello");
var Timer = document.getElementById("timer");
Timer.innerHTML = "hello";
writehere();
</script>
html代码放在这里.....
【问题讨论】:
是否有id为“timer”的元素?调用函数时元素是否可用? 你确定 DOM 已经加载了吗? 如果在head部分调用,timer div还不存在。 嗨..是的,在正文部分我给出了一个 div id="timer"(由于格式问题,我没有在此处发布 html 部分)是不是 document.write 在头部被执行 您的 html 中可能有它,但在您的代码运行时它尚未加载。 【参考方案1】:您的问题很可能是在您的代码执行时 DOM 尚未准备好。对于您的示例,您可能只需将其移至页面底部即可。
一般来说,在执行需要与 DOM 交互的 javascript 之前,您需要确保 DOM 已完全加载,如果您使用 jQuery,您可以在文档就绪函数中调用您的代码以确保 DOM 已加载,例如
$(document).ready(
);
看看这个 SO question for vanilla javascript 等价物
What is the non-jQuery equivalent of '$(document).ready()'?
【讨论】:
是的,将其移至页面底部后,它起作用了..谢谢 “一般来说,在执行 javascript 之前,您需要确保 DOM 已完全加载”对我来说这听起来像是一个糟糕的建议,在大多数情况下这是不需要的,并且总是使用它听起来比如(无意冒犯你)“我不知道自己在做什么,但这样做会奏效” 你的权利,我应该写的是“在执行将修改或与 DOM 交互的 Javacsript 之前”。显然你不应该把所有的代码都放在那里。我已经相应地修改了我的答案。 在执行一段 JavaScript 代码时,只需要确保脚本使用的“所有需要的 DOM 元素”被加载,而不是“完整的 DOM”。所以这对我来说仍然是一个不好的建议,请查看我的答案以了解更多信息。你怎么看? 我同意你的观点,只有你需要 DOM 的代码才应该等到它准备好,这就是为什么我根据你之前的评论修改了我的答案,说“需要 DOM 的 JavaScript”,你是说您应该检查 DOM 的特定部分是否已准备好,而不是完整的 DOM?无论如何,我感谢您解释您的推理。【参考方案2】:我认为您的问题是 DOM 尚未加载,因此没有 id="Timer" 的 div 元素。您应该在 onLoad 事件上调用此方法。
【讨论】:
如果你这样做了,那么document.write
将删除现有文档。
感谢大家抽出宝贵的时间,所以现在我明白了所有关于加载 DOM 的内容。
@Quentin:你能告诉我这个吗,即使 dom 已经准备好并且你做了一个 document.write 文件不是被清除了吗?
@DhirajBodicherla — “即使”是什么意思?如果 DOM 是完整的,那么文档将关闭,写入它会重新打开它并丢弃它。问题中的代码并没有等待 DOM 完成。【参考方案3】:
这都是关于 HTML 标签元素和执行时间的。在您的示例中,脚本定位在head tag,因此在执行脚本时,元素 div#timer 根本不存在。
那么你有两个解决方案:
将脚本移至the end of the page(标签前), 延迟脚本的执行usingonload
event
如果您的 DOM 并不复杂,并且不包含 img
标签或任何需要从网络获取的元素,则不需要使用 onload
。您可以在两种情况下使用它:
一般来说,将script
标签放在文档末尾是否被认为是一种好习惯(因此您不需要使用onload
),它可以防止 Flash Of Unstyled Content (FOUC) . Javascript 会阻止您的浏览器渲染引擎。因此,如果在内容可供用户使用之前放置 JavaScript 标记(读取:在 head 标记中),浏览器将执行它,DOM 几乎是空的,并且在此执行期间用户只会看到一个空白页面。
另外,关于jQuery.fn.ready
方法,你必须注意这一点:
$(document).ready(function()
// my first useless function
console.log( "first", 1 );
);
$(document).ready(function()
// my second useless function
// this function will throw an (intentional) error
console.log( "second", someUndefinedVariable );
);
$(document).ready(function()
// my third useless function
// because the previous function contains an error
// this function will never be called
console.log( "third ", 3 );
);
假设您正在使用一些插件,并且您有一些手写代码等等。如果每个插件和您的代码都使用jQuery.fn.ready
方法,并且由于某种原因(假设在某些情况下在某些特定浏览器版本中)一个函数抛出错误,那么这个函数之后的所有处理程序将永远不会运行...
此外,这样做会在最后延迟所有“真正的”JavaScript 执行,如果队列中有很多方法要运行,那么您可能会在几秒钟内阻塞浏览器,并且用户会通知它。
【讨论】:
以上是关于函数调用中的 document.write 和 innerHTML的主要内容,如果未能解决你的问题,请参考以下文章
前端JS面试题汇总 Part 3 (宿主对象与原生对象/函数调用方式/call与apply/bind/document.write)