javascript - 有没有办法在不使用 Shadow DOM 的情况下将类似 <slot> 的元素添加到 <template> 中?

标签 javascript html web-component shadow-dom

为了遵守 DRY 原则,我想创建一个基于 <template> 的自定义组件。代码看起来像这样(请原谅我在通宵达旦后在手机上打字时的偷工减料):

// base.html

<template id="player">
  <div class="card">
    <div class="card-body">
      <slot name="user-username"></slot>
    </div>
  </div>
</template>

// app.js

class PlayerCard extends HTMLElement {  
  constructor(){
    super();
    let tmpl = querySelector...;
    this.appendChild(tmpl.content.cloneNode();
  }
}

define('player-card', PlayerCard);

// index.html

{% for user in users %}
  <player-card>
    <div slot="user-username">{{ user }}</div>
  </player-card>
{% end for %}

但在梦想破灭和长时间的研究之后,我了解到插槽只能在 Shadow DOM 中使用。使用 SDOM 的问题是内部样式受到保护,不能直接受外部 CSS 影响。

这意味着,一方面,我无法将数据注入(inject)到模板实例中,也无法在不重新实现 Bootstrap 的情况下使用 Shadow DOM。

我被困住了。对于我的大脑来说,一定有一种方法可以实现这一点,但我的大脑无法找到它 - 要么因为它太复杂,要么因为它太琐碎和容易。

请问有什么建议吗?

最佳答案

是的,<SLOT>s只能在shadowDOM内部使用

但是您可以使用样式槽做更多事情。

长答案请参阅:::slotted CSS selector for nested children in shadowDOM slot

customElements.define('player-card', class extends HTMLElement {
    constructor() {
      let template = (id) => document.getElementById(id).content.cloneNode(true);
      super()
         .attachShadow({mode: 'open'})
         .append(template(this.nodeName));
      this.onclick = (evt) => this.style.color='blue';
    }
});
/* GLOBAL CSS */
player-card { /* inheritable styles trickle down into shadowDOM */
  font: 20px Arial;
  color: green;
}
[slot="username"] { /* lightDOM styles are REFLECTED to SLOTs */
  width: 200px;
  border: 2px solid green;
}
<template id="PLAYER-CARD">
  <style shadowDOM-CSS > 
    div { /* styles do not style content in SLOTs */
      padding: 1em;
      background:gold;
    }
    ::slotted(*) { /* slotted can only style the lightDOM 'skin' */
      background: lightgreen;
    }
  </style>
  <div>
    <slot name="username"></slot>
  </div>
</template>

<player-card>
    <!-- lightDOM, hidden when shadowDOM is used, then REFLECTED to SLOT -->
    <div slot="username">Ahmed</div>
</player-card>

<player-card>
    <!-- lightDOM, hidden when shadowDOM is used, then REFLECTED to SLOT -->
    <div slot="username">Danny</div>
</player-card>

关于javascript - 有没有办法在不使用 Shadow DOM 的情况下将类似 <slot> 的元素添加到 <template> 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65984517/

相关文章:

javascript - 在 Web 组件中扩展元素时, "is"语法有何意义?

Javascript:类构造函数基础知识 - 在单独的方法中定义属性

javascript - 无法在react-native中加载图像

javascript - TypeScript:匿名类工厂

javascript when 函数和任意数量的请求

html - Base64 编码的 SVG 无法通过 HTML 标记中的内联样式或通过 CSS 中的类进行着色

javascript - 如何在 Golang 中遍历数据并在 Javascript 中使用时创建唯一 ID

iphone - 通过 HTML 代码在 UIView 中使用透明背景色

javascript - 另一个 React 组件中的新 React 模块

javascript - 影子 DOM : is it possible to encapsulate JS?