Reputation: 563
i try to create custom element with js. this is my custom element
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)
and this is my pug template
img-bg(src="/static/images/email.svg")
p(slot="slot-content") cek
i want to append p element inside the slot. but the p element appended after the #shadow-root.
can anyone solve this... :( sorry for the bad english
Upvotes: 2
Views: 2120
Reputation: 10945
The <slot>
tag is used to import children of the element into the <slot>
and not a place for you to put your own children.
The best you could do is to wrap your <slot>
in something else and then place the component's <p>
tag just after the <slot>
.
Alternatively, and not recommended:
If you want to add any tag, generated by the component, into the slot then you need to place the tag as a child of your element and not into the shadowDOM. As long as it is placed as a proper child, matching the requirements of the <slot>
than it should show in the <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>
So the only way to add into the slot is to add child elements to the element.
That is probably not a good thing to do since you are altering the content that the user of your component created. And that could mess up their code, CSS or both.
Upvotes: 0
Reputation: 31171
<slot>
is defined in Shadow DOM v1. Therefore you mus use attachShadow()
instead of createShadowRoot()
:
this.attachShadow({ mode:'open'}).appendChild(wrapper)
Upvotes: 1