首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何单独包装开槽元素

如何单独包装开槽元素
EN

Stack Overflow用户
提问于 2020-02-25 11:51:16
回答 2查看 568关注 0票数 1

是否有一种方法可以将每个单独的元素分隔到特定槽名的阴影区域中?

假设标记看起来类似于

代码语言:javascript
复制
<custom-element>
  <div name="item">item 1</div>
  <div name="item">item 2</div>
</custom-element>

目前,呈现类似于:

代码语言:javascript
复制
<custom-element>
  <div class="wrap">
    <div name="item">item 1</div>
    <div name="item">item 2</div>
  </div>
</custom-element>

我将如何包装有槽的元素以输出,类似于:

代码语言:javascript
复制
<custom-element>
  <div class="wrap">
    <div name="item">item 1</div>
  </div>
  <div class="wrap">
    <div name="item">item 2</div>
  </div>
</custom-element>

我目前(有缺陷的)方法:

代码语言:javascript
复制
customElements.define('custom-element', class MyCustomElement extends HTMLElement {

  constructor(...args) {
    super(...args);

    let shadow = this.attachShadow({mode: open});
    shadow.innerHTML = `
      <div class="wrap">
        <slot name="item"></slot>
      </div>
    `;
  }
});
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-26 15:23:16

我建议你改变你对孩子们包装的态度。最简单的方法是将缺失的HTML添加为开槽div的子程序,如下例所示。您仍然可以使用::slotted伪选择器对时隙元素进行样式设置。

代码语言:javascript
复制
customElements.define('custom-element', class MyCustomElement extends HTMLElement {

  constructor(...args) {
    super(...args);

    let shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
      <style>
        ::slotted([slot="item"]) {
            border: 1px solid black;
            padding: 15px;
        }
      </style>
      <slot name="item"></slot>
    `;

  }
});
代码语言:javascript
复制
<custom-element>
  <div slot="item">
    <div class="wrap">item 1</div>
  </div>
  <div slot="item">
    <div class="wrap">item 2</div>
  </div>
</custom-element>

这种方法背后的原因是,包装最终属于子元素,并且应该与每个子元素一起使用。结果将与您所要求的类似。

尽管,如果您确实想动态地向元素添加包装,那么您可以处理slotchange事件。只要填充了一个插槽,并且可以从ShadowRoot元素中听到该事件,就会触发该事件。在事件中,assignedElements上的回调循环(它们是槽中的元素)并更改它们的innerHTML值。

代码语言:javascript
复制
customElements.define('custom-element', class MyCustomElement extends HTMLElement {

  constructor(...args) {
    super(...args);

    let shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `<slot name="item"></slot>`;

    shadow.addEventListener('slotchange', event => {
      const { target } = event;
      const assignedElements = target.assignedElements();
      for (const element of assignedElements) {
        if (element.querySelector('.wrap') === null) {
          const wrapper = document.createElement('div');
          wrapper.className = 'wrap';
          
          for (const node of element.childNodes) {
            wrapper.appendChild(node);
          }
          
          element.append(wrapper);
        }
      }
    });

  }
});
代码语言:javascript
复制
.wrap {
  border: 1px solid black;
  padding: 15px;
}
代码语言:javascript
复制
<custom-element>
  <div slot="item">item 1</div>
  <div slot="item">
    <div class="wrap">item 2</div>
  </div>
</custom-element>

票数 2
EN

Stack Overflow用户

发布于 2022-07-17 22:14:10

我也面临过同样的问题,这就是我想出的解决方案:重新定位项目插槽。我有一个“主”槽,它应该始终是空的--在每个slotchange事件上,我迭代新项,为每个条目创建一个新的包装器,并在每个包装器中创建一个动态生成的名称。然后,我将更改原始项的“槽”属性,将其移动到该时隙。

代码语言:javascript
复制
customElements.define('buttons', class extends HTMLElement {

    __allocateId()
    {
        var i = 0;
        while ( this.__buttons.has( "btn" + i ) ) {
            ++i;
        }
        return "btn" + i;
    }

    __onButtonSlotChange(button)
    {
        if (button.contentSlot.assignedNodes({flatten: true}).length == 0) {
            this.__buttons.delete(button.id);
            button.remove();
        }
    }

    __onMainSlotChange() {
        for (var element of this.mainSlot.assignedElements({flatten: true})) {
            var button = document.createElement('arrow-button');
            button.id = this.__allocateId();
            this.shadowRoot.appendChild(button);

            var subSlot = document.createElement('slot');
            subSlot.name = button.id;
            button.appendChild(subSlot);
            button.contentSlot = subSlot;
            subSlot.addEventListener('slotchange', this.__onButtonSlotChange.bind(this, button));

            element.setAttribute("slot", button.id);

            this.__buttons.set(button.id, button);
        }
    }

    constructor() {
        super();
        this.__buttons = new Map();
    }

    connectedCallback() {
        var shadowRoot = this.attachShadow({mode: 'open'});

        this.mainSlot = document.createElement('slot');
        shadowRoot.appendChild(this.mainSlot);

        var buttonList = document.createElement('div');
        shadowRoot.appendChild(buttonList);

        this.mainSlot.addEventListener('slotchange', this.__onMainSlotChange.bind(this));
    }
});

这对原始对象的影响最小,在对“按钮”代码进行任何修改时,整个组件的行为都是正确的-例如。项删除触发相应按钮的删除。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60393993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档