自定义元素升级时如何执行脚本
How to execute a script when the custom element is upgraded
我已经定义了一个自定义元素,我只想在自定义元素升级到其注册类型时执行脚本。用例是我必须调用自定义方法。
我的主要 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 从主文件移动到另一个自定义元素中)。
同步HTML导入
正如@dandavis 所建议的,由于 <link>
和 <script>
元素的 sync
默认行为,您只需按正确的顺序放置标签:注册之前方法调用。
或者您可以在触发 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
事件。此时import里面的|<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
在这种情况下,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。
通过自定义元素模块中的 import
加载依赖项。例如,依赖于 Highcharts 的自定义元素模块(例如something.mjs
):
import '/node_modules/highcharts/highcharts.js'
class Something extends HTMLElement {}
customElements.define('x-something', Something)
我已经定义了一个自定义元素,我只想在自定义元素升级到其注册类型时执行脚本。用例是我必须调用自定义方法。
我的主要 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 从主文件移动到另一个自定义元素中)。
同步HTML导入
正如@dandavis 所建议的,由于 <link>
和 <script>
元素的 sync
默认行为,您只需按正确的顺序放置标签:注册之前方法调用。
或者您可以在触发 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
事件。此时import里面的|<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
在这种情况下,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。
通过自定义元素模块中的 import
加载依赖项。例如,依赖于 Highcharts 的自定义元素模块(例如something.mjs
):
import '/node_modules/highcharts/highcharts.js'
class Something extends HTMLElement {}
customElements.define('x-something', Something)