在附加到 DOM 之前和之后更改自定义元素内容

问题描述 投票:0回答:1

我创建了一个自定义 HTML 元素,它从以下模板创建一个新元素:

<template id="track">
  <div class="record">Nothing yet</div>
</template>

这里是定义自定义元素的JS代码:

class Track extends HTMLElement {

  constructor() {
    super();    
    this.template = document.getElementById("track");
    this.clone = this.template.content.cloneNode(true);
  }
    
  connectedCallback() {    
    this.append( this.clone );
  }
  
  set record(html) { 
    // Case 1: Works only for element 1 (before appending to the DOM)
    this.clone.querySelector('.record').innerHTML = html;
    // Case 2: Works only for element 2 (after appending to the DOM)
    //this.querySelector('.record').innerHTML = html;
  }
}


customElements.define('my-track', Track);

请注意更改

<div>
的 HTML 内容的记录属性。我希望能够更新元素内容,无论它是否已附加到 DOM。我无法编写在这两种情况下都有效的代码(在将自定义元素附加到 DOM 之前和之后)。以下代码仅适用于情况 1:

const el1 = document.createElement('my-track');
el1.record = "Bla<b>bla</b> #1";
document.body.append(el1);

以下代码仅适用于情况2

const el2 = document.createElement('my-track');
document.body.append(el2);
el2.record = "Bla<b>bla</b> #2";

当然,在方法

set record()
中,我可以检查元素是否已经附加到DOM并相应地切换到情况1或情况2。但我觉得这不是构建自定义元素的正确方法。

在方法中更新元素内容的最佳选项是什么

set record()
无论元素是否已附加到 DOM?

我在这里创建一个 JSFiddle:https://jsfiddle.net/Alphonsio/gL8a239o/13/

javascript custom-element html-templates
1个回答
0
投票

当没有 DOM 时,你无法向 DOM 写入任何内容。

就像还没有房子的时候,你不能在客厅放沙发一样。

这意味着您必须在

this.isConnected
方法中使用
set record
检查该元素是否附加到 DOM。

它是 JavaScript 类/对象的实例;您当然可以将任何您想要的东西附加到它并让

constructor/attributeChangedCallback/connectedCallback
处理它(但要仔细考虑房子/客厅的场景)

const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);

customElements.define('my-track', class extends HTMLElement {
  connectedCallback() {
    this.append(
      this.recordDIV = createElement("div", {
        innerHTML: `Default Record content`
      }))
  }

  set record(html) {
    if (this.isConnected)
      this.recordDIV.innerHTML = html;
    else
      console.warn(this.id, "Not in the DOM yet")
  }
});

const el1 = createElement('my-track', {
  id: "el1"
});
el1.record = "Record #1";
document.body.append(el1);


const el2 = createElement('my-track', {
  id: "el2"
});
document.body.append(el2);
el2.record = "Record #2";

© www.soinside.com 2019 - 2024. All rights reserved.