【问题标题】:HTML Templates and HTML Import - Inner Script not Executing in FirefoxHTML 模板和 HTML 导入 - 内部脚本不在 Firefox 中执行
【发布时间】:2016-01-27 20:42:15
【问题描述】:

我正在使用 webcomponents.js 来填充 Firefox 对 Web 组件的支持。

当通过 HTML 导入加载 HTML 模板时,一旦将基于模板的自定义元素添加到主页的 DOM 中,模板内的脚本就不会执行。

它在 Chrome 中运行网站时会执行(支持原生 Web 组件)。

但是,当模板放置在主页本身时,Firefox 和 Chrome 都会执行此类脚本。

请参阅HTML5Rocks 的 Eric Bidelmann 的示例。这在 Chrome 和 Firefox 中都可以运行(通过 webcomponents.js)——只要模板位于同一个 HTML 文件中。

<!DOCTYPE html>
<html>
<body>

<button onclick="useIt()">Use me</button>
<div id="container"></div>
<script>
  function useIt() {
    var content = document.querySelector('template').content;
    // Update something in the template DOM.
    var span = content.querySelector('span');
    span.textContent = parseInt(span.textContent) + 1;
    document.querySelector('#container').appendChild(
        document.importNode(content, true));
  }
</script>

<template>
  <div>Template used: <span>0</span></div>
  <script>alert('Thanks!')</script>
</template>



</body>
</html>

但当模板文本显示时,它不会在通过 HTML 导入链接加载模板及其内容时运行。如前所述,它会加载内容,但不会在 Firefox 中执行脚本。

这是 webcomponents.js 中的错误,还是 Firefox 中的错误? 任何人都有解决方法的好主意(“使用 Polymer 或 Angular”除外)?

注意 - 这是基于使用 Firefox 43 和 Chrome 47。

【问题讨论】:

  • IDK,我在 Firefox 42 上运行良好,OSX:jsfiddle.net/tuq0wj1y
  • 以上示例在 Firefox 和 Chrome 中有效 - 无效的是将
  • 您是否在控制台中收到任何沙盒警报?

标签: javascript html firefox web-component html5-template


【解决方案1】:

这不是 Firefox 中的错误,Internet Explorer 11 具有相同的行为(使用 webcomponents.js)。

importNode 方法不是由 webcomponents.js 填充的。这就是为什么&lt;script&gt; 元素在导入时没有被激活。

有一个与该问题相关的issue opened

我的解决方法:我不在导入的 &lt;template&gt; 中插入脚本标签 &lt;script&gt;(JS/HTML 分隔:)。

此外,您可以解析您的 &lt;template&gt; 以查找 &lt;script&gt; 标签并尝试手动激活/执行它们(可能有点棘手...)

【讨论】:

    【解决方案2】:

    我确实找到了解决此问题的方法,它允许在激活模板元素时执行脚本。

    这依赖于这样一个事实,即 HTML 导入会立即执行位于导入文件中的脚本,如果它们不在模板标签内。 所以解决方案是在导入文件中再添加一个 HTML 导入并将脚本加载为外部资源 - 一旦模板激活并立即执行,就会加载。

    所以不要在外部导入文件中包含以下内容:

    <template>
      <div>Template used: <span>0</span></div>
      <script>alert('Thanks!')</script>
    </template>
    

    你有这个:

    <template>
      <div>Template used: <span>0</span></div>
      <link rel="import" href="script1.html">
    </template>
    

    并且引用的 script1.html 文件包含以下内容:

      <script>
          alert('Thanks!')
      </script>
    

    是的,这又是一个 HTTP 请求,但它可行且简单。

    这解决了必须在模板元素初始化时运行的任何脚本。稍后激活所需的脚本可以通过函数定义或内联脚本实现。

    注意:
    另一种解决方法是在模板部分下方(和外部)的外部导入文件中添加一个“div”标签,并使用 id="script1",然后使用一些 JS 提取 div 的内容并将脚本标签添加到模板中。既然你无论如何都需要 JS 来激活模板,这并没有太大的变化,但这感觉更像是一种 hack。

    【讨论】:

    • 这是(一种)正确提供熟食而不是生垃圾的方法:import->cooked-template = RAW。当我构建一个模块时,我希望该模块无论我如何拉入它都能正常工作。幸运的是,我的项目在本地文件系统上,所以我不担心拉取请求,只是以那些方式提供服务东西都煮熟了。
    • 然而,就填充模板而言,这确实使代码编写复杂化。
    • 这是一个奇怪的解决方法,不知何故感觉不安全,但除了笨重的架构之外,我还没有找到不使用它的充分理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2019-06-11
    • 1970-01-01
    • 2023-03-25
    • 2017-06-05
    • 2017-08-03
    • 2012-02-13
    相关资源
    最近更新 更多