Javascript 如何在升级自定义元素时执行脚本

Javascript 如何在升级自定义元素时执行脚本,javascript,html,web-component,custom-element,html-imports,Javascript,Html,Web Component,Custom Element,Html Imports,我已经定义了一个自定义元素,我只想在自定义元素升级到其注册类型时执行脚本。用例是我必须调用一个自定义方法 我的主html文件如下所示: <project-list></project-list> <script> var project_list = document.getElementsByTagName("project-list")[0] project_list.custom_method("some_data"); </scr

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

我的主html文件如下所示:

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

var project_list=document.getElementsByTagName(“项目列表”)[0]
项目列表。自定义方法(“某些数据”);
自定义元素在HTML导入中注册,如下所示:

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

“严格使用”;
var currentScript=document._currentScript | | document.currentScript;
类ProjectList扩展了HtmleElement{
createdCallback(){
控制台日志(“已创建”);
}
自定义方法(数据){
log(“custom_method()OK”);
控制台日志(数据);
this.innerHTML=数据;
}
}
文件登记册(“项目清单”,项目清单);
我的问题很简单:如何确保只有在自定义元素获得其
custom\u方法后才调用主html文件中的脚本?


我在寻找一个优雅的解决方案。这是规范作者应该想到的。我不介意对体系结构进行太多的更改(例如,如果有必要,可以将javascript从主文件移动到另一个自定义元素中)。

同步HTML导入

正如@dandavis所建议的,由于
元素的
sync
默认行为,您只需按正确的顺序放置标记:在方法调用之前注册

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

window.onload=function()
{
var project_list=document.getElementsByTagName(“项目列表”)[0]
项目列表。自定义方法(“某些数据”)
}

“严格使用”;
var currentScript=document._currentScript | | document.currentScript;
类ProjectList扩展了HtmleElement{
createdCallback(){
控制台日志(“已创建”);
}
自定义方法(数据){
log(“custom_method()OK”);
控制台日志(数据);
this.innerHTML=数据;
}
}
文件登记册(“项目清单”,项目清单);

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

import '/node_modules/highcharts/highcharts.js'

class Something extends HTMLElement {}

customElements.define('x-something', Something)

在实现规范的浏览器上,创建元素并附加它将是同步的。不过,就硬编码标记而言,目前还没有类似于DOM事件的“allComponentsReady”。一种方法是从组件内部引发
文档
上的自定义事件,并将该事件像
onload()事件一样用于需要自定义方法的页面代码。您还可以研究redux之类的东西,以一种不会让人讨厌的方式连接许多不同的web组件和应用程序方法。@dandavis:我就是这么做的。但我也设置了一面旗帜。如果设置了该标志,则组件已经设置,并且可以立即执行自定义方法。否则,它将被安排在事件触发时。我已经用我使用的代码发布了一个答案。@dandavis:连接许多不同的web组件:如果某些web组件依赖于其他组件,那么它必须等到所有其他组件就绪后,才能设置/发送自己的标志/事件。当然,您可以使用自延迟模式等待任何内容:
(函数wait(){If(!project_list.custom_method)返回setTimeout(wait,50);project_list.custom_method(“some_data”);}())
如果需要,您可以在其中列出更多的预请求。这在Chrome上可行,但在使用Polymer polyfill的Firefox上无效。它始终是异步的。我认为这与此错误有关:对于跨浏览器解决方案,我已更新了答案。@user6020072:该错误表示不应阻止异步.HTML导入,根据规范,可以是同步的,也可以是异步的。请阅读此处:这同样有效:
HTMLImports.whenReady(function(){…});