html自定义元素,#shadow-root后附加的插槽内容

时间:2018-05-17 01:43:41

标签: javascript html html5 pug shadow-dom

我尝试用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元素。但是在#shadow-root之后追加了p元素。

enter image description here

任何人都可以解决这个问题...... :(抱歉英语不好

2 个答案:

答案 0 :(得分:1)

<slot>在Shadow DOM v1中定义。因此,您可以使用attachShadow()代替createShadowRoot()

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

答案 1 :(得分:0)

<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或两者兼而有之。