我目前正在研究CustomHtmlElement,我对调用构造函数的顺序有一个误解.

例如,如果我有两个CustomHtmlElement:

class ExForm extends HTMLElement {
  constructor() {
    super();
    console.log(`${this.getAttribute('name')} constructor ${performance.now()}`);
    //debugger;
  }
  
  connectedCallback() {
    console.log(`${this.getAttribute('name')} connected ${performance.now()}`);
  }
}

customElements.define("ex-form", ExForm);

class ExInput extends HTMLElement {
  constructor() {
    super();
    
    console.log(`${this.getAttribute('name')} constructor ${performance.now()}`);
    //debugger;
  }
  
   connectedCallback() {
    console.log(`${this.getAttribute('name')} connected ${performance.now()}`);
  }
}

customElements.define("ex-input", ExInput);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ex-form name="form1">
      <ex-input name="input1" ></ex-input>
    </ex-form>
    <ex-form name="form2">
      <ex-input name="input2"></ex-input>
    </ex-form>
  </body>
  <script src="./index.js"></script>
</html>

我原以为构造函数的执行顺序是:

Form1,Input1,Form2,Input2

然而,当我执行代码时,顺序是:

Form1、Form2、Input1、Input2

有人能解释一下为什么构造函数的执行顺序和呈现给页面的HTML元素的顺序不一致吗?

推荐答案

这取决于Web组件的定义时间.

StackOverflow代码片段中的JS代码将运行after the DOM is parsed,因此现有的自定义元素将为102(最初被解析为HTMLUnknownElement)

ex-form is defined first, so all existing <ex-form> will be upgraded first.
Then ex-input is defined, and all existing <ex-input> are upgraded next.

(参见下面的代码片段)如果您移动DOM被解析的declaration-before,您将获得预期的顺序:

总的来说:不要依赖DOM中的顺序,您无法控制用户/开发人员何时加载您的Web组件文件.

如果您需要判断依赖项,则有customElements.whenDefined( )个.

<script>
  class BaseClass extends HTMLElement {
    constructor() {
      super();
      console.log(`constructor ${this.nodeName} `, this.innerHTML);
    }

    connectedCallback() {
      console.log(`${this.nodeName} connected ${this.innerHTML}`);
    }
  }
  customElements.define("ex-form", class extends BaseClass {});
  customElements.define("ex-input", class extends BaseClass {});
</script>
<ex-form>
  <ex-input></ex-input>
  <ex-input></ex-input>
</ex-form>
<ex-form>
  <ex-input></ex-input>
</ex-form>

Javascript相关问答推荐

React存档iframe点击行为

D3多线图显示1线而不是3线

是否有方法在OpenWeatherMap API中获取过go 的降水数据?

使用JavaScript在ionic Web应用程序中更新.pane和.view的背景 colored颜色

仅圆角的甜甜圈图表

为什么当我解析一个promise时,输出处于挂起状态?

如何从HTML对话框中检索单选项组的值?

使用Google API无法进行Web抓取

从Nextjs中的 Select 项收集值,但当单击以处理时,未发生任何情况

邮箱密码重置链接不适用于已部署的React应用程序

Phaser3 preFX addGlow不支持zoom

通过跳过某些元素的对象进行映射

JavaScript&;Reaction-如何避免在不使用字典/对象的情况下出现地狱?

在JavaScript中,有没有一种方法可以迭代字符串的词法标记?

React数组查找不读取变量

如何使用useparams从react路由中提取id

使用Java脚本筛选数组中最接近值最小的所有项

如何从嵌套的json中获取最大值

单击子按钮时将活动切换类添加到父分区

如何将PNG图像放在wix站点的Open Streemap map 上,使PNG图像成为 map 不可分割的一部分?