html - 如何在自定义元素*及其子元素*已初始化时获得回调

标签 html prototype custom-element

我正在嵌套自定义元素。我想让我的父自定义元素使用其子自定义元素原型(prototype)中的方法和属性。例如

<script>      
var ChildElement = Object.create(HTMLElement.prototype);

ChildElement.getName = function () {
  return "Bob";
}

document.registerElement("child-element", { 
  prototype: ChildElement
});

var ParentElement = Object.create(HTMLElement.prototype);

ParentElement.createdCallback = function () {
  var self = this;
  setTimeout(function () {
    // This logs 'Bob', correctly
    console.log(self.childNodes[0].getName());  
  }, 0);

  // This explodes - getName is not defined.
  console.log(self.childNodes[0].getName());
};

document.registerElement("parent-element", { 
  prototype: ParentElement
});
</script>

<parent-element><child-element></child-element></parent-element>

如内联所述,父元素无法读取子元素原型(prototype)上定义的任何内容。不过,如果它立即触发 setTimeout,它就可以;只需要等到该元素的子节点也设置完毕即可。

出现这种情况是因为元素创建期间的回调顺序,我认为是这样的:

  • 设置了父元素的原型(prototype)(从 HTMLElement 到 ParentElement)
  • 调用父级的 createdCallback
  • 调用父级的attachedCallback
  • 设置了 child 的原型(prototype)(从 HTMLElement 到 ChildElement)
  • 调用了 child 的 createdCallback
  • 调用 child 的attachedCallback

此时触发 createdCallback 是有道理的,但据我所知,当所有子级都已创建时,根本没有回调可用。我认为这意味着如果不使用 setTimeout 等待整个页面完成渲染,就不可能在使用子元素原型(prototype)的创建过程中做任何事情。

是否有任何可以从父节点监听的回调或事件,仅在所有子节点的原型(prototype)也已设置时触发?是否有不同的方法可以让您使用这样的结构?除了触发 setTimeout,您还有什么可以做的吗?

我认为自定义元素旨在允许与其他元素内容进行参数化,并且在该内容中有效地不支持自定义元素是非常令人惊讶的。

可以认为这可以被认为是 Prototype not defined when accessing children on creation of custom-tag 的副本.然而,这个问题措辞不当,示例不完整,唯一的答案似乎实际上是一个实现错误,而不是解决方案(或者至少,它不再是当前的浏览器行为)

最佳答案

实际上,有许多不同的方法可以使用嵌套的自定义元素来实现这一点。

直接的方法是向父元素添加自定义回调,子元素将通过其 attachedCallback 方法调用该回调:

ParentElement.childAttachedCallback = function ()
{
    console.log( this.childNodes[0].getName() )
}

ChildElement.attachedCallback = function()
{
    this.parentElement.childAttachedCallback()
}

在复杂的情况下,您可以改用:

  • Promise 对象,由父级设置并由一个或多个子级解决,
  • 由 child 触发并由 parent 捕获的自定义事件,
  • MutationObserver 对象设置为观察父子列表中的变化......

关于html - 如何在自定义元素*及其子元素*已初始化时获得回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36187227/

相关文章:

javascript - 我如何在没有 Node.Js 的情况下使用 FileSaver.js 模块?

javascript - 为什么这些绑定(bind)函数的 "this"上下文在每个新实例中都相同?

javascript - 当我在函数中返回 'this' 时,代码表现不同

javascript - CustomElements V1 和 ShadowDOM 的外部样式

javascript - ES6 自定义元素继承

html - 如何在将鼠标悬停在不同 div 中的另一个图像上时显示图像

javascript - Roweditor 中的 Ext JS 复选框

python - 从站点获取数据,而这些数据在 Python 的主 HTML 文件中找不到

javascript - 扩展函数原型(prototype)

css - 具有 Web 组件的应用程序的全局 CSS