Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QuerySelector not finding template on HTML import

I am currently trying to learn how to use web components (without the use of Polymer) using the latest stable Chrome 52 (I have also tried this with the webcomponents.js polyfill on Chrome 52). However, when I do I seem to get an error with the querySelector. When I attempt to grab the (admittedly poorly named template id) in the console via document.querySelector('#template') it is null and is unable to find it.

I am using this guide albeit with some ES6 syntax. (I also tried direct copy and paste and it had the same issue)

I also tried to search within the shadowDOM, but it didn't exist there either.

view.html

<template id="template">
  <style>
  </style>
  <div class="container">
    <h1>WZView</h1>
  </div>
</template>
<script>
"use strict";

class WZView extends HTMLElement {

  createdCallback () {
    var root = this.createShadowRoot();
    var template = document.querySelector('#template');
    root.appendChild(document.importNode(template.content, true));
  }

}

document.registerElement('wz-view', WZView);
</script>

index.html

<!DOCTYPE html>
<html>
<head>
<!--<script src="/bower_components/webcomponentsjs/webcomponents.js"></script>-->
<link rel="import" href="view.html">
</head>
<body>
  <wz-view></wz-view>
</body>
</html>

console:

view.html:16 Uncaught TypeError: Cannot read property 'content' of null
> document.querySelector('#template')
null
like image 769
Alyssa Herzog Avatar asked Jun 06 '16 19:06

Alyssa Herzog


1 Answers

In the <script>s inside the imported HTML, don't use document.querySelector(...).

Use:

// while inside the imported HTML, `currentDocument` should be used instead of `document`
var currentDocument = document.currentScript.ownerDocument;
...
// notice the usage of `currentDocument`
var templateInsideImportedHtml = currentDocument.querySelector('#template');

Example (fixing the example in the question):

var currentDocument = document.currentScript.ownerDocument; // <-- added this line

class WZView extends HTMLElement {
    createdCallback () {
        var root = this.createShadowRoot();
        var template = currentDocument.querySelector('#template'); // <-- changed this line
        root.appendChild(document.importNode(template.content, true));
    }
}

Compatibility:

Only IE 11 won't support it. Most browsers (including Edge) implement it, and for IE 10 and below there is a polyfill.

like image 95
acdcjunior Avatar answered Oct 07 '22 17:10

acdcjunior