如何在自定义元素升级时执行脚本 [英] How to execute a script when the custom element is upgraded

查看:94
本文介绍了如何在自定义元素升级时执行脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了一个自定义元素,并且只在自定义元素升级到其注册类型时才执行脚本。用例是我必须调用自定义方法。

我的主html文件如下所示:

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

自定义元素在HTML导入中注册,如下所示:

 < script> 
使用严格;
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>

我的问题很简单:如何确保主html文件中的脚本被调用只有在自定义元素获得 custom_method 方法后?



我正在寻找一个优雅的解决方案。规格作者会想到的东西。我不介意相当多地更改架构(例如,如果有必要,可以将javascript从主文件移动到另一个自定义元素中)。

解决方案

同步HTML导入



根据@dandavis的建议,由于同步 < link> < script> 元素的默认行为,您只需要按照正确的顺序放置标签:在方法调用之前注册。

或者您可以在 DOMContentLoaded window.onload时调用您的自定义方法

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

 <项目列表>< /项目列表><脚本> 严格使用; var currentScript = document._currentScript || document.currentScript; class ProjectList扩展HTMLElement {createdCallback(){console.log(created); } custom_method(data){console.log(custom_method()OK);的console.log(数据); this.innerHTML =数据; }} document.registerElement(project-list,ProjectList);< / script>  

异步HTML导入



如果由于某些原因您想要异步加载HTML导入文件,可以等待 link.onload 事件。此时,导入中的| < script> 已经执行,自定义元素已注册并创建。

 < HTML> 
< head>
< title>< / title>
< meta charset =utf-8/>
< link rel =importhref =projectList.htmlid =projectListasync>
< 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>

使用WebComponents.js填充



在这种情况下,加载导入后,polyfill不会立即实例化创建的对象。相反,您应该听取 WebComponentsReady 事件:

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

它适用于Firefox,IE 11,也与Chrome。


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).

解决方案

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.

这篇关于如何在自定义元素升级时执行脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆