html5模板内容(文档片段)在appendChild上加载顺序

时间:2015-12-30 21:45:16

标签: javascript html html5 dom html5-template

请考虑以下代码 - >

<template id="foo">
    <script type="text/javascript">
        console.log("00000000");
    </script>

    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

    <script type="text/javascript">
        console.log(11111111);
    </script>
    <script type="text/javascript">
        console.log(22222222);
        var xyz = $;
        console.log(33333333);
    </script>
</template>

现在将此附加到DOM

var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.appendChild(clone);

在控制台中提供此输出 - &gt;

   00000000
   11111111
   22222222
   Uncaught ReferenceError: $ is not defined

所以问题一般是 - &gt;

如何正确加载到DOM,一个html <template>  一个外部脚本(在这种情况下就像jQuery),后面跟一个内联脚本有一些依赖

此外 - 如果删除模板标记,则不会发生这种情况 - &gt;

   <script type="text/javascript">
        console.log("00000000");
    </script>

    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

    <script type="text/javascript">
        console.log(11111111);
    </script>
    <script type="text/javascript">
        console.log(22222222);
        var xyz = $;
        console.log(33333333);
    </script>

在后一种情况下,浏览器是如何同步下载的?

是否可以在前一种情况下(使用模板)逐行下载阻止脚本?

2 个答案:

答案 0 :(得分:0)

问题是脚本是异步加载的。这意味着它开始从Web加载脚本,但继续运行下面的代码。因此,在这种情况下,它将在不加载jQuery的情况下执行下面的代码。

您只需要加载一次,这样您就可以在开始时进行,只需加载一次:

var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.body.appendChild(clone);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<template id="foo">
  <script type="text/javascript">
    console.log(00000000);
  </script>

  <script type="text/javascript">
    console.log(11111111);
  </script>
  <script type="text/javascript">
    console.log(22222222);
    var xyz = $;
    console.log(33333333);
  </script>
</template>

另一种选择是确保下面的代码只在加载文件后执行:

var template = document.getElementById('foo')
var clone = document.importNode(template.content, true);
document.body.appendChild(clone);
<template id="foo">
  <script type="text/javascript">
    console.log(00000000);
  </script>

  <script type="text/javascript">
    function scriptOnload() {
      console.log(11111111);
      console.log(22222222);
      var xyz = $;
      console.log(33333333);
    }
  </script>

  <script onload="scriptOnload()" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</template>

答案 1 :(得分:0)

这是我在应用程序中(使用jQuery)处理它的方式:

//Load the template from an external file and append it to the HEAD of the document
$.get("/path/to/your_external_template_file.html", function (html_string) {
    $('head', top.document).append(
        new DOMParser().parseFromString(html_string, 'text/html').querySelector('template')
    );
}, 'html');

//Locate the template after you've imported it
var $template = $("#top_template_element_id");

//If you want to reuse the content, be sure to clone the node.
var content = $template.prop('content').cloneNode(true);

//Add a copy of the template to desired container on the page
var $container = $('#target_container_id').append(content);