15

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

我的主 html 文件如下所示:

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

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

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

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

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

4

2 回答 2

5

同步 HTML 导入

正如@dandavis 所建议的那样,由于and元素的sync默认行为,您只需要将标签按正确的顺序放置:在方法调用之前注册。<link><script>

或者,您可以在触发DOMContentLoaded或事件时调用您的自定义方法,如下所示:window.onload

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>

异步 HTML 导入

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

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

使用 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。

于 2016-03-05T00:09:05.443 回答
0

import通过自定义元素模块中的an 加载依赖项。例如,一个something.mjs依赖于 Highcharts 的自定义元素模块(例如):

import '/node_modules/highcharts/highcharts.js'

class Something extends HTMLElement {}

customElements.define('x-something', Something)
于 2020-08-07T14:50:01.833 回答