HTML пользовательский элемент, содержимое слота добавляется после # shadow-root - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь создать пользовательский элемент с помощью js. это мой пользовательский элемент

class ImageBackground extends HTMLElement {
  createdCallback() {
    let src = this.hasAttribute('src') ? this.getAttribute('src') : '/static/images/user.png'
    let className = `img-bg ${this.hasAttribute('className') ? this.getAttribute('className') : ''}`
    let isLazy = this.getAttribute('lazy') !== false

    const slotContent = document.createElement('slot')
    slotContent.setAttribute('name', 'slot-content')

    const wrapper = document.createElement('div')
    wrapper.appendChild(slotContent)
    wrapper.style.backgroundImage = `url("${src}")`
    wrapper.style.backgroundSize = 'cover'
    wrapper.style.backgroundPosition = 'center'
    wrapper.style.height = '300px'
    wrapper.setAttribute('class', className)

    this.createShadowRoot().appendChild(wrapper)
  }
}

document.registerElement('img-bg', ImageBackground)

а это мой шаблон мопса

img-bg(src="/static/images/email.svg")
      p(slot="slot-content") cek

Я хочу добавить элемент p внутри слота. но элемент p добавляется после # shadow-root.

enter image description here

может кто-нибудь решить это ... :( извините за плохой английский

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Тег <slot> используется для импорта дочерних элементов элемента в <slot>, а не для размещения собственных детей.

Лучшее, что вы можете сделать, - это обернуть ваш <slot> во что-то еще, а затем поместить тег <p> компонента сразу после <slot>.

.

В качестве альтернативы и не рекомендуется:

Если вы хотите добавить любой тег, сгенерированный компонентом, в слот, то вам нужно поместить тег как дочерний элемент вашего элемента, а не в shadowDOM. До тех пор, пока он помещен как надлежащий дочерний элемент, соответствующий требованиям <slot>, чем это должно быть указано в <slot>.

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'}).innerHTML = `
    <style>
      .wrapper {
        border: 1px solid black;
        padding: 5px;
      }
      ::slotted(*) {
        background-color: #8F8; 
        margin: 1px;
        padding: 5px;
      }
    </style>
    <p>Before Slot</p>
    <div class="wrapper"><slot>Hi There</slot></div>
    <p>After Slot</p>
    `;
  }

  connectedCallback() {
  }
}

customElements.define('my-el', MyEl);

function addChild() {
  var el = document.querySelector('my-el');
  var p = document.createElement('p');
  p.textContent = "New stuff as a child.";
  el.appendChild(p);
}

var button = document.querySelector('#one');
button.addEventListener('click', addChild);
p {
  font-family: tahoma;
}

my-el p {
  font-weight: bold;
}
<p>Before Element</p>
<my-el>
  <p>Stuff in the slot</p>
</my-el>
<p>After Element</p>
<hr/>
<button id="one">Add Child</button>

Таким образом, единственный способ добавить в слот - это добавить дочерние элементы к элементу.

Вероятно, это нехорошо, поскольку вы изменяете контент, созданный пользователем вашего компонента. И это может испортить их код, CSS или оба.

0 голосов
/ 20 мая 2018

<slot> определяется в Shadow DOM v1. Поэтому вы должны использовать attachShadow() вместо createShadowRoot():

this.attachShadow({ mode:'open'}).appendChild(wrapper)
...