admin管理员组文章数量:1336139
Using Custom Elements, I would like to style the elements inside the custom element, but when I define the element, everything besides the shadow dom disappears.
How do I move the content from the element to the shadow dom? I already have a wrapper element (<div class="wrapper">
) inside the shadow, but trying to use
wrapper.innerHTML = this.innerHTML;
doesn't work.
HTML
<site-card>
<section title>
...
</section>
<section body>
...
</section>
<section actions>
<button class="modern small">Action</button>
<button class="modern small">Action 2</button>
</section>
</site-card>
JS
"use strict";
class cardElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('div');
wrapper.setAttribute('class','wrapper');
wrapper.innerHTML = this.innerHTML;
var style = document.createElement('style');
style.textContent = ... /* CSS removed to shorten. */
shadow.appendChild(style);
shadow.appendChild(wrapper);
};
};
customElements.define('site-card', cardElement);
Using Custom Elements, I would like to style the elements inside the custom element, but when I define the element, everything besides the shadow dom disappears.
How do I move the content from the element to the shadow dom? I already have a wrapper element (<div class="wrapper">
) inside the shadow, but trying to use
wrapper.innerHTML = this.innerHTML;
doesn't work.
HTML
<site-card>
<section title>
...
</section>
<section body>
...
</section>
<section actions>
<button class="modern small">Action</button>
<button class="modern small">Action 2</button>
</section>
</site-card>
JS
"use strict";
class cardElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('div');
wrapper.setAttribute('class','wrapper');
wrapper.innerHTML = this.innerHTML;
var style = document.createElement('style');
style.textContent = ... /* CSS removed to shorten. */
shadow.appendChild(style);
shadow.appendChild(wrapper);
};
};
customElements.define('site-card', cardElement);
Share
edited Mar 29, 2019 at 6:39
Christopher Bradshaw
2,7835 gold badges27 silver badges41 bronze badges
asked Feb 12, 2018 at 1:43
James MJames M
5611 gold badge5 silver badges7 bronze badges
2
- Wele to SO. Please include all relevant lines of code, its output and explain the expected result versus what you get. – marekful Commented Feb 12, 2018 at 1:54
- @marekful Thanks! I have added the HTML and JS. – James M Commented Feb 13, 2018 at 2:46
2 Answers
Reset to default 5If you want to control the CSS from outside of the custom element then just use <slot>
. <slot>
embeds the children into the slot but leaves CSS control to outside the element.
class cardElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('slot');
var style = document.createElement('style');
style.textContent = `
[title] {
background-color: #060;
color: #FFF;
}
[body] {
background-color: #600;
color: #FFF;
}
[actions] {
background-color: #006;
color: #FFF;
}
`;
shadow.appendChild(style);
shadow.appendChild(wrapper);
};
};
customElements.define('site-card', cardElement);
[title] {
background-color: #0F0;
color: #000;
}
[body] {
background-color: #F00;
color: #000;
}
[actions] {
background-color: #00F;
color: #000;
}
<site-card>
<section title>
This is the title
</section>
<section body>
This is the body
</section>
<section actions>
<button class="modern small">Action</button>
<button class="modern small">Action 2</button>
</section>
</site-card>
If you want to control the CSS from inside the element then you need to migrate the children. But this can not be done in the constructor. This section of the spec explains the limitations on the constructor.
You need to move the children in the connectedCallback
class cardElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({mode: 'open'});
this._wrapper = document.createElement('div');
var style = document.createElement('style');
style.textContent = `
[title] {
background-color: #060;
color: #FFF;
}
[body] {
background-color: #600;
color: #FFF;
}
[actions] {
background-color: #006;
color: #FFF;
}
`;
shadow.appendChild(style);
shadow.appendChild(this._wrapper);
};
connectedCallback() {
while(this.firstElementChild) {
this._wrapper.appendChild(this.firstElementChild);
}
}
};
customElements.define('site-card', cardElement);
[title] {
background-color: #0F0;
color: #000;
}
[body] {
background-color: #F00;
color: #000;
}
[actions] {
background-color: #00F;
color: #000;
}
<site-card>
<section title>
This is the title
</section>
<section body>
This is the body
</section>
<section actions>
<button class="modern small">Action</button>
<button class="modern small">Action 2</button>
</section>
</site-card>
I would suggest avoiding using
innerHTML
since that will wipe out any event handlers, etc. that might already exist. It may actually be slower depending on the number of direct children. It could also mess up any children that may be custom elements.
You should do it a bit later, in window.onload
:
class cardElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({ mode: 'open' });
var wrapper = document.createElement('div');
wrapper.setAttribute('class', 'wrapper');
window.onload = () => {
wrapper.innerHTML = this.innerHTML;
};
var style = document.createElement('style');
style.textContent = ... /* CSS removed to shorten. */
shadow.appendChild(style);
shadow.appendChild(wrapper);
}
};
customElements.define('site-card', cardElement);
本文标签: javascriptIs it possible to keep the inner html of a custom elementStack Overflow
版权声明:本文标题:javascript - Is it possible to keep the inner html of a custom element? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742402848a2468232.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论