HTML Templates and HTML Import - Inner Script not Executing in Firefox

余生长醉 提交于 2019-12-13 19:32:02

问题


I am using webcomponents.js to polyfill Firefox support of web components.

When loading an HTML template through an HTML import, a script within the template does not execute once the custom-element based on the template is added to the DOM of the main page.

It does execute when running the site in Chrome (which has native web components support).

However, both Firefox and Chrome execute such script when the template is placed within the main page itself.

See the example from Eric Bidelmann at HTML5Rocks. This runs both in Chrome and in Firefox (via webcomponents.js) - as long as the template is located in the same HTML file.

<!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>

But while the template text shows, it does NOT run when loading the template and its content via a HTML import link. As mentioned, it loads the content, but isn't executing the script in Firefox.

Is this a bug in webcomponents.js, or a bug in Firefox? Anyone having a good idea for workarounds (other than "use Polymer or Angular")?

Note - this is based on using Firefox 43 and Chrome 47.


回答1:


It is not a bug in Firefox, Internet Explorer 11 has the same behaviour (with webcomponents.js).

The importNode method is not polyfilled by webcomponents.js. That's why <script> elements are not activated when they are imported.

There an issue opened related to that problem.

My workaround: I don't insert scripts tags <script> inside an imported <template> (JS/HTML separated:).

Also, you could parse your <template> looking for <script> tags and try to activate/execute them manually (could be somewhat tricky...)




回答2:


I did find a workaround for this issue which allows for script execution when the template element is activated.

This relies on the fact that HTML imports execute scripts located in the imported file immediately if they are not located inside a template tag. So the solution is to just add one more HTML import inside the import file and load the script as external resource - this gets loaded once the template activates and executes right then and there.

So instead of having the below in the external import file:

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

you have THIS:

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

and the referenced script1.html file contains the following:

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

Yes, it's one more HTTP request, but it's workable and simple.

This solves any script which must run upon initialization of a template element. Script needed for later activation can be materialized in terms of function definitions, or inline scripts.

Note:
Another workaround is to add a "div" tag in the external import file below (and outside) the template section with an id="script1" and then use some JS to extract the div's content and add a script tag instead into the template. Since you anyway need JS to activate the template it's not much of a change,but this feels more like a hack.



来源:https://stackoverflow.com/questions/35047590/html-templates-and-html-import-inner-script-not-executing-in-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!