Mikhail Boyarsky
Mikhail Boyarsky

Reputation: 3028

How to access elements of imported html from script inside imported html

I want to make a custom element which will self-register on html import.

custom-element.html:

<html>
  <...>
  <body>
    <template id="myTemplate">
    </template>
  </body>
  <script src="my-script.js">
</html>

my-script.js:

let customElementPrototype = Object.create(HTMLElement.prototype);
customElementPrototype.createdCallback = function () {
  // somewhere here i want to access <template> to insert it in element
  // I've tried document.querySelector("#myTemplate") and
  // document.currentScript.ownerDocument.querySelector.querySelector("#myTemplate")
  // they don't work either, result of querySelector is null
}
document.registerElement("custom-element", customElementPrototype);

Usage:

<html>
<head>
  <link rel="import" href="custom-element.html">
</head>
<...>

Upvotes: 4

Views: 2660

Answers (1)

pherris
pherris

Reputation: 17743

Inside the createdCallback the context is the custom-element and not the ownerDocument. You can see this by console.log(this); inside the createdCallback which logs (from my plunker example):

<div is="custom-element">
</div>

In my-script.js you can capture a reference to the ownerDocument and use it inside your callback. This will allow your custom-element to access both it's own DOM and the DOM of the imported HTML. e.g.

var mainDoc = document.currentScript.ownerDocument;

The full my-script.js (script.js in my plunker):

var mainDoc = document.currentScript.ownerDocument;

var CustomElementPrototype = Object.create(HTMLElement.prototype);
CustomElementPrototype.createdCallback = function () {
  console.log(this); //the div 
  //import the contents of the template
  var clone = document.importNode(mainDoc.querySelector('#myTemplate').content, true);
  //append template to div
  this.appendChild(clone);
};

document.registerElement("custom-element", {
    prototype: CustomElementPrototype,
    extends: 'div'
});

combined with a template that has some default value (this document will be available via mainDoc):

<html>
  <body>
    <script src="script.js"></script>
    <template id="myTemplate">
      hello world
      <br>
      from template
    </template>
  </body>
</html>

And the HTML to pull it all in and use it:

<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <link rel="import" href="custom-element.html">
  </head>

  <body>
    <h1>Hello Plunker!</h1>
    <div is="custom-element"></div>
  </body>

</html>

https://plnkr.co/edit/jO3ci8vLxolHhvtGxJQ5

This was a helpful reference: http://webcomponents.org/articles/introduction-to-html-imports/

Upvotes: 4

Related Questions