【问题标题】:document.head, document.body to attach scriptsdocument.head, document.body 附加脚本
【发布时间】:2011-09-26 15:59:12
【问题描述】:

我经常使用并看到推荐的 dom-access 结构,用于动态向页面添加内容:

loader = document.createElement('script');
loader.src = "myurl.js";
document.getElementsByTagName('head')[0].appendChild(loader);

现在,我偶然发现这可以在 Google chrome 中使用:

document.head.appendChild(loader);

再调查一下,我发现这很有效,显然是跨浏览器:

document.body.appendChild(loader);

所以我的主要问题是:我有什么理由不应该像这样将元素附加到 BODY 上?

另外,您认为document.head 会得到更广泛的支持吗?

【问题讨论】:

标签: javascript dom


【解决方案1】:

我看不出在实践中将<script> 元素插入<head><body> 元素有什么意义。理论上,我认为运行时 DOM 类似于可能的静态 DOM 是件好事。

至于document.head,它是 HTML5 的一部分,显然已经在所有主流浏览器的最新版本中实现(请参阅http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-head)。

【讨论】:

  • 添加一个样式表作为插件怎么样,你希望人们能够从他们位于头部的 CSS 覆盖某些样式,而不必在所有内容中添加 !important
【解决方案2】:

document.body 是 DOM 规范的一部分,我看不出为什么不使用它。但请注意:

在有内容的文档中,返回元素,在框架集文档中,返回最外层的元素。

(来自https://developer.mozilla.org/en/DOM/document.body

document.head 目前没有在任何 DOM 规范中定义显然我错了,请参阅 Daniel 的回答),因此您通常应该避免使用它。

【讨论】:

    【解决方案3】:

    我尝试实现此代码并遇到了一些麻烦,所以想分享我的经验。

    首先我尝试了这个:

    <script>
    loader = document.createElement('script');
    loader.src = "script.js";
    document.getElementsByTagName('head')[0].appendChild(loader);
    </script>
    

    在 script.js 文件中,我有如下代码:

    // This javascript tries to include a special css doc in the html header if windowsize is smaller than my normal conditions.  
    winWidth = document.etElementById() ? document.body.clientWidth : window.innerWidth; 
    if(winWidth <= 1280) { document.write('<link rel="stylesheet" type="text/css" href="style/screen_less_1280x.css">'); } 
    

    问题是,当我执行所有这些操作时,代码无法正常工作。而它确实在我将脚本加载器替换为以下内容时起作用:

    <script src="script.js"></script>
    

    这对我有用,所以问题现在解决了,但我想了解这两种方法之间的区别。为什么一个有效而另一个无效?

    更重要的是,在script.js中我也有这样的代码:

    function OpenVideo(VideoSrcURL) {
    window.location.href="#OpenModal";
    document.getElementsByTagName('video')[0].src=VideoSrcURL;
    document.getElementsByTagName('video')[0].play();}
    

    并且该代码确实可以正常工作,无论我以哪种方式在我的 html 文件中获取脚本。

    所以我的窗口大小调整脚本不起作用,但视频内容可以。因此,我想知道行为差异是否与“文档”对象有关......?也许“文档”引用的是 script.js 文件而不是 html 文件。

    我不知道。以为我应该分享这个问题,以防它适用于其他任何人。

    干杯。

    【讨论】:

    • 我知道这真的很晚了,但你真的很亲密。 el = document.createElement('script'); el.src = 'script.js'; var parent = document.getElementsByTagName('head').item(0) ||文档.文档元素; parent.appendChild(el);
    • 你为什么把你的问题作为答案? -1 所以你会这样做
    【解决方案4】:

    目前给出的答案集中在两个不同的方面,并且都非常有用。

    如果您需要可移植性,那么在您无法控制 DOM 一致性的文档中,检查您必须将脚本附加到的元素是否存在可能会很有用;这样,当 HEAD 部分没有被显式创建时,它也可以工作:

    var script = document.createElement('script');
    var parent = document.getElementsByTagName('head').item(0) || document.documentElement;
    parent.appendChild(script);
    

    除了 CORS 策略和其他容易检测到的逻辑错误之外,我看不到这个 DOM 操作任务应该失败的情况,所以在我看来,检查 document.body 作为后备是没有必要的。

    正如其他用户所概述的那样,document.head 在发布问题时尚未得到广泛支持,因为它是 HTML5 规范,而 document.body 是,这就是为什么您看到后者在所有浏览器上都工作.

    所以你可以通过以下方式获得 HEAD:

    document.head || document.getElementsByTagName('head').item(0)
    

    但我认为它不是很有用,因为后者永远不会出错,并且是可读且标准的 DOM 查询,除非您发现 document.head 从性能角度来看更快。

    我可以看到此表单的另一个可能的优势是代码从旧 JavaScript 转换为更现代的 HTML5 兼容代码,简洁且更具可读性。

    如果兼容性是必须的,您可以使用强制可移植性的库所采用的技巧(例如来自 Google、Yandex 和其他公司的解决方案):

    var parent = document.getElementsByTagName('head')[0] || document.documentElement.firstChild;
    parent.appendChild(script);
    

    这样,在不太可能的情况下,HEAD 元素不存在,而 BODY(或其他元素)存在,您可以确保将脚本附加到它。

    我还添加了一个有用的一点:当设置了src 属性并且它被附加到DOM 时,脚本源的HTTP 请求是从浏览器发送的。无论这两个条件以何种顺序满足,这两个事件中的最后一个都会导致 HTTP 请求被分派。

    【讨论】:

    • 为什么不先检查document.head
    • 确认这点属实:alert(document.head == document.getElementsByTagName('head').item(0))
    • 解释代码,你就有了最好的跨浏览器答案!从中获取一点点:stackoverflow.com/questions/12113412/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    相关资源
    最近更新 更多