相关疑难解决方法(0)

在connectedCallback中等待Element Upgrade:FireFox和Chromium差异

2023 年 3 月更新

注意:这是有效的,因为在下一个刻度中,lightDOM 中的N 个(不是全部!)DOM 元素将被解析。

对于 (app.) N > 1000你会遇到麻烦,因为延迟将在解析所有 N 个元素之前结束。

因此,要么添加(大约 20 行)代码来实际检查所有 lightDOM 是否已解析。(但是由于您的 DOM 正在遭受 Obesitas 的困扰,因此您可能还会遇到其他性能问题)

或者只是保持 lightDOM中N 个 DOM 元素的数量较小。

当然,您稍后在解析之后添加的任何 DOM都不会影响任何内容(当不触发时)connectedCallback

2021 年 3 月更新:

FireFox 错误已修复,现在的行为与 Chromium 和 Safari 相同。

这意味着等待 JS EventLoop 为空(带有setTimeoutrequestAnimationFrame)现在connectedCallback是一个跨浏览器方法

connectedCallback(){
 setTimeout(()=>{
   // can access lightDOM here
 }); // ,0 not required
}
Run Code Online (Sandbox Code Playgroud)

事件循环到底是什么?- 菲利普·罗伯茨 …

callback class-method web-component custom-element

10
推荐指数
1
解决办法
1245
查看次数

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

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

<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>
Run Code Online (Sandbox Code Playgroud)

如内联所述,父级无法读取子元素原型上定义的任何内容.它可以,如果它立即触发一个setTimeout; 它只需要等到这个元素的子节点也被设置好了.

看起来这是因为元素创建过程中的回调顺序,我认为是这样的:

  • 设置父级的原型(从HTMLElement到ParentElement)
  • 调用父级的createdCallback
  • 调用父级的attachCallback
  • 设置了孩子的原型(从HTMLElement到ChildElement)
  • 调用孩子的createdCallback
  • 调用孩子的attachCallback

在这一点上,createdCallback触发是有道理的,但据我所知,当你所有的孩子都被创建时,根本没有可用的回调.我认为这意味着不可能在使用子元素原型的创建上做任何事情,而不使用setTimeout等待整个页面完成渲染.

是否有任何可以从父级监听的回调或事件,只有在设置了所有子节点的原型后才会触发?是否有一种不同的方法可以让你使用这样的结构?除了触发setTimeout之外,还有什么可以做的吗?

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

可以说,这可以被认为是在创建custom-tag时访问子节​​点时未定义Prototype的副本.然而,这个问题的措辞很差,破坏的例子,唯一的答案似乎实际上是一个实现错误,而不是解决方案(或者至少,它不再是当前的浏览器行为)

html html5 prototype custom-element

6
推荐指数
1
解决办法
891
查看次数

如何处理“一旦你的元素不再连接就可以调用connectedCallback”编码Web组件

我的问题中粘贴的声明是从https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks复制的。

作为一名没有 WebComponent 经验的开发人员,我试图了解迄今为止推荐的所有经验法则和最佳实践。

继续阅读它说“...使用 Node.isConnected 来确保”。它的含义很明显:检查它是否仍然连接,但至少对我来说,尚不清楚我应该采取什么措施来解决它,或者在某些情况下我应该期待什么。

我的情况是我正在创建一个 Web 组件来侦听 SSE(服务器发送事件)。这对于 alife 仪表板和其他几个场景非常有用。SSE事件在从Kafka Stream消费后基本上将由NodeJs或Spring Webflux响应。

到目前为止,我所做的所有简单示例都没有遇到任何元素在连接回调期间不再连接的问题。

此外,我没有阅读最佳实践中关于“不再连接的元素”的任何建议。

我读了一些精彩的讨论:

可以在光盘之前调用自定义元素连接回调多次吗

从那里我了解到我始终可以信任这个生命周期构造函数 -->connectedCallback -->disconnectedCallback。

当所有子自定义元素已连接时如何拥有“connectedCallback”

基本上我了解到没有一个特定的方法“在所有孩子都升级后调用”

这两个问题都接近我的问题,但它没有回答我:应该注意哪些挑战或风险,或者如何解决“一旦元素不再连接,可能会调用connectedCallback”的可能性?在我上述的情况下,我是否缺少任何治疗?我是否应该创建一些观察者,当该元素不再可用时触发,以重新创建事件源对象并再次向此类事件源对象添加侦听器?

我粘贴了下面的代码进行说明,完整的 Web 组件示例可以从https://github.com/jimisdrpc/simplest-webcomponet克隆,其后端可以从https://github.com/jimisdrpc/simplest-kafkaconsumer克隆。

const template = document.createElement('template');
template.innerHTML = `<input id="inputKafka"/> `;

class InputKafka extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {

    this.attachShadow({mode: 'open'})
    this.shadowRoot.appendChild(template.content.cloneNode(true))

    const inputKafka = this.shadowRoot.getElementById('inputKafka');

    var source = new EventSource('http://localhost:5000/kafka_sse');

    source.addEventListener('sendMsgFromKafka', function(e) {
      console.log('fromKafka');
      inputKafka.value = e.data;
    }, false);

  }
  attributeChangedCallback(name, …
Run Code Online (Sandbox Code Playgroud)

html javascript web-component custom-element native-web-component

6
推荐指数
1
解决办法
3096
查看次数