函数调用中的 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(标签前), 延迟脚本的执行using onload 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的主要内容,如果未能解决你的问题,请参考以下文章

控制来自第三方的 document.write 调用的范围

前端JS面试题汇总 Part 3 (宿主对象与原生对象/函数调用方式/call与apply/bind/document.write)

# document.write和document.insert区别

js循环调用函数问题

JS随笔5

js常用函数