Search code examples
htmlecmascript-6web-componentes6-modules

How to get document.currentScript.ownerDocument in <script type="module">?


How i can get ownerDocument in script type="module"?

<template>
  text
</template>
<script type="module">
  let owner = document.currentScript.ownerDocument // is null
  
  // But i need get <template>
  
  let tpl = owner.querySelector('template')
</script>


Solution

  • The spec clearly states that when using <script type="module"> the document.currentScript property is set to null during execution. See spec under "execute a script block".

    Which, of course, is obvious if using src attribute. The source has no way of knowing it will be called by a script tag and not an import statement (or both). When inlining the module there always is a script tag, but my guess is that they want to make the experience consistent.

    If your document actually is the window.document that is still available as a global. Otherwise you have two options if you still want the script to be loaded as a module:

    • Not the prettiest; create a global above the module and store the template.

      <script type="text/javascript">
      window.myTemplates = ((ns) => {
        const owner = window.document.currentScript.ownerDocument;
        ns.fancyButton = owner.querySelector("template");
        return ns;
      })(window.myTemplates || {});
      </script>
      
      <script type="module">
      const tpl = window.myTemplates.fancyButton;
      // ...
      </script>
      
    • Don't write the template as a HTML template and instead as a ES/JS template. Your editor may not support highlighting literal HTML and linting of the tags is a problem.

      <script type="module">
      const tpl = window.document.createElement("template");
      tpl.innerHTML = `
        <strong>example</strong>
        <span style="background-color: rgba(127,127,127,0.6);">text</span>
      `;
      // ...
      </script>