javascript - 是否可以保留自定义元素的内部 html?

标签 javascript html web-component native-web-component

使用自定义元素,我想在自定义元素中设置元素的样式,但是当我定义元素时,除了 shadow dom 之外的所有内容都消失了。

如何将内容从元素移动到影子 dom?我已经在阴影中有一个包装器元素 ( <div class="wrapper"> ),但我正在尝试使用

wrapper.innerHTML = this.innerHTML;

不起作用。

HTML

<site-card>
  <section title>
    ...
  </section>
  <section body>
    ...
  </section>
  <section actions>
    <button class="modern small">Action</button>
    <button class="modern small">Action 2</button>
  </section>
</site-card>

JS

"use strict";
class cardElement extends HTMLElement {
    constructor() {
        super();
        var shadow = this.attachShadow({mode: 'open'});
        var wrapper = document.createElement('div');
        wrapper.setAttribute('class','wrapper');
        wrapper.innerHTML = this.innerHTML;
        var style = document.createElement('style');
        style.textContent = ... /* CSS removed to shorten. */
        shadow.appendChild(style);
        shadow.appendChild(wrapper);
    };
};
customElements.define('site-card', cardElement);

最佳答案

如果您想从自定义元素外部控制 CSS,则只需使用 <slot> . <slot>将子元素嵌入到槽中,但将 CSS 控制留给元素外部。

class cardElement extends HTMLElement {
  constructor() {
    super();
    var shadow = this.attachShadow({mode: 'open'});
    var wrapper = document.createElement('slot');
    var style = document.createElement('style');
    style.textContent = `
    [title] {
      background-color: #060;
      color: #FFF;
    }
    [body] {
      background-color: #600;
      color: #FFF;
    }
    [actions] {
      background-color: #006;
      color: #FFF;
    }
    `;
    shadow.appendChild(style);
    shadow.appendChild(wrapper);
  };
};
customElements.define('site-card', cardElement);
[title] {
  background-color: #0F0;
  color: #000;
}
[body] {
  background-color: #F00;
  color: #000;
}
[actions] {
  background-color: #00F;
  color: #000;
}
<site-card>
  <section title>
    This is the title
  </section>
  <section body>
    This is the body
  </section>
  <section actions>
    <button class="modern small">Action</button>
    <button class="modern small">Action 2</button>
  </section>
</site-card>

如果您想从元素内部控制 CSS,则需要迁移子元素。但这不能在构造函数中完成。 This section of the spec解释构造函数的限制。

您需要移动 connectedCallback 中的子项

class cardElement extends HTMLElement {
  constructor() {
    super();
    var shadow = this.attachShadow({mode: 'open'});
    this._wrapper = document.createElement('div');
    var style = document.createElement('style');
    style.textContent = `
    [title] {
      background-color: #060;
      color: #FFF;
    }
    [body] {
      background-color: #600;
      color: #FFF;
    }
    [actions] {
      background-color: #006;
      color: #FFF;
    }
    `;
    shadow.appendChild(style);
    shadow.appendChild(this._wrapper);
  };
  
  connectedCallback() {
    while(this.firstElementChild) {
      this._wrapper.appendChild(this.firstElementChild);
    }
  }
};
customElements.define('site-card', cardElement);
[title] {
  background-color: #0F0;
  color: #000;
}
[body] {
  background-color: #F00;
  color: #000;
}
[actions] {
  background-color: #00F;
  color: #000;
}
<site-card>
  <section title>
    This is the title
  </section>
  <section body>
    This is the body
  </section>
  <section actions>
    <button class="modern small">Action</button>
    <button class="modern small">Action 2</button>
  </section>
</site-card>

I would suggest avoiding using innerHTML since that will wipe out any event handlers, etc. that might already exist. It may actually be slower depending on the number of direct children. It could also mess up any children that may be custom elements.

关于javascript - 是否可以保留自定义元素的内部 html?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48738474/

相关文章:

javascript - 是否可以使用 axios-mock-adapter 将部分数据与 onPost() 匹配?

javascript - 带有复选框和 NgFor 的自定义 CSS

javascript - 无法从模板获取内容

javascript - (几乎)总是在闭包中定义 Polymer?

javascript - 在 web 组件中引用 light DOM

javascript - 在 FlatList React Native 中仅显示 10 条记录

javascript - JavaScript 中的 HTML 复选框开/关检测

javascript - 隐藏一个 bootstrap 表头

javascript - Foundation – 深层链接到 Accordion 选项卡?

javascript - 如何使用javascript隐藏ul标签内的div标签