Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute a script when the custom element is upgraded

I have defined a custom element and I want to execute a script only when the custom element is upgraded to its registered type. The use case is that I must call a custom method.

My main html file looks like this:

<project-list></project-list>
<script>
    var project_list = document.getElementsByTagName("project-list")[0]
    project_list.custom_method("some_data");
</script>

The custom element is registered in a HTML import like this:

<script>
  "use strict";
  var currentScript = document._currentScript || document.currentScript;

  class ProjectList extends HTMLElement {

    createdCallback(){
      console.log("created");
    }

    custom_method(data) {
      console.log("custom_method() OK");
      console.log(data);

      this.innerHTML = data;
    }

  }

  document.registerElement("project-list", ProjectList);
</script>

My question is simple: how to make sure the script in the main html file is called only after the custom element gains its custom_method method?

I'm looking for an elegant solution. Something that the spec authors would have thought of. I don't mind changing the architecture quite a bit (for example by moving the javascript from the main file into another custom element if that is necessary).

like image 334
Mildred Avatar asked Mar 04 '16 20:03

Mildred


People also ask

How do custom elements work?

The functionality of a custom element is defined using an ES2015 class which extends HTMLElement . Extending HTMLElement ensures the custom element inherits the entire DOM API and means any properties/methods that you add to the class become part of the element's DOM interface.

What is a custom element and when do we use them?

“What's The Point Of Custom Elements?” # The basic idea is that if you create an element that always performs the same role and has the same set of properties and functions applied to it, then you should be able to name it after what it does.

How do I create a custom element?

Steps involved in creating a Custom HTML Element:Create a new Class representing the New Element (ES6) Extend the class from “HTMLElement” Add “connectedCallback” function to the class to access DOM Element when the element is added to the document. Access the Custom DOM Element using “this” keyword.

How to execute a script when the element is being clicked in HTML?

Execute a script when the element is being clicked in HTML? Execute a script when the element is being clicked in HTML? Use the onclick attribute to execute a script when the element is clicked in HTML. You can try to run the following code to implement onclick attribute −

How to use custom elements in HTML?

Once a custom element is defined, we can use it on par with built-in HTML elements. That’s great, as HTML dictionary is rich, but not infinite. There are no <easy-tabs>, <sliding-carousel>, <beautiful-upload> … Just think of any other tag we might need. We can define them with a special class, and then use as if they were always a part of HTML.

What is customized built-in elements?

Customized built-in elements – extending built-in elements, like a customized button, based on HTMLButtonElement etc. First we’ll cover autonomous elements, and then move to customized built-in ones.

How to check if an element has been upgraded or not?

You can use window.customElements.whenDefined ("my-element") which returns a Promise that you can use to determine when an element has been upgraded. window.customElements.whenDefined ('my-element').then ( () => { // do something after element is upgraded })


1 Answers

Sync HTML Import

As suggested by @dandavis, because of the sync default behaviour of the <link> and <script> elements, you just have to put your tags in the right order: registration before method call.

Or instead you can call your custom method when the DOMContentLoaded or the window.onload event is fired, as below:

window.onload = function() 
{
    var project_list = document.getElementsByTagName("project-list")[0]
    project_list.custom_method("some_data")     
}
<project-list></project-list>

<script>
  "use strict";
  var currentScript = document._currentScript || document.currentScript;

  class ProjectList extends HTMLElement {

    createdCallback(){
      console.log("created");
    }

    custom_method(data) {
      console.log("custom_method() OK");
      console.log(data);

      this.innerHTML = data;
    }

  }

  document.registerElement("project-list", ProjectList);
</script>

Async HTML Import

If for some reasons you want to load your HTML Import file asynchronousely, you can wait for the link.onload event. At this time the |<script> inside the import has been already exectued, the custom element registered and created.

<html>
<head>
  <title></title>
    <meta charset="utf-8" />
    <link rel="import" href="projectList.html" id="projectList" async>
    <script>
    projectList.onload = function ()
    {
      console.log( "import {loaded}" )
      var project_list = document.getElementsByTagName( "project-list" )[0]
      project_list.custom_method("some_data")
    } 
    </script>
</head>
<body>
    <project-list id="pl"></project-list>
    <script>
        console.warn( "custom_method is " + pl.custom_method ) //undefined
    </script>
</body>
</html>

With WebComponents.js polyfill

In this situation the polyfill won't instantiate the created object immediately after the import is loaded. Instead you should listen to the WebComponentsReady event:

document.addEventListener( "WebComponentsReady", function ()
{
    console.log( "WebComponentsReady" )
    var project_list = document.getElementsByTagName( "project-list" )[0]
    project_list.custom_method( "some_data" )
} )

It works with Firefox, IE 11, and also with Chrome.

like image 148
Supersharp Avatar answered Oct 01 '22 19:10

Supersharp