如何在 Web 组件中的伪 ;:before 元素(或 :;after)的 css 内容 属性 中获取插槽内容?
how to get a slot content in the css content property of a pseudo ;:before element (or :;after) in a web component?
好吧,我认为问题在标题中:
在具有 shadowRoot 的 Web 组件中,我想在伪 ::before 或 ::after 元素的内容 属性 中使用插槽 text-content。
这可以让我获得更多台词。
您有想法、建议或解决方案吗?
您可以使用 CSS 自定义属性作为 ::before
和 ::after
的 content
和 slotchange
事件的来源来实现此目的:
<!DOCTYPE html>
<html lang="en">
<head>
<title>WC</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
class XTest extends HTMLElement {
constructor() {
super();
// add shadow dom and insert template content
const shadowRoot = this.attachShadow({ mode: "open" });
const template = document.getElementById("x-test-template");
const templateContent = template.content;
shadowRoot.appendChild(templateContent.cloneNode(true));
}
connectedCallback() {
// get all the named slots
const slots = this.shadowRoot.querySelectorAll("slot[name]");
[...slots].forEach(slot => {
// add a listener to run when the slot changes
slot.addEventListener("slotchange", event => {
// get the slot name
const name = event.target.name;
// get the slot content
const text = event.target.assignedNodes()[0].textContent;
// update the custom property
this.style.setProperty(`--content-${name}`, `'${text}'`);
});
});
}
}
customElements.define("x-test", XTest);
</script>
</head>
<body>
<template id="x-test-template">
<style>
:host {
display: inline-block;
position: relative;
font-size: 2rem;
padding: 2rem;
}
:host::before,
:host::after {
content: "";
position: absolute;
top: 0;
font-size: 1rem;
}
:host::before {
/* set the pseudo selector content to the custom property */
content: var(--content-before, "");
left: 0;
}
:host::after {
/* set the pseudo selector content to the custom property */
content: var(--content-after, "");
right: 0;
}
slot[name] {
display: none;
}
</style>
<!-- slot for ::before -->
<slot name="before"></slot>
<!-- default slot -->
<slot></slot>
<!-- slot for ::after -->
<slot name="after"></slot>
</template>
<x-test>
<span slot="before">B</span>
<span>Hello</span>
<span slot="after">A</span>
</x-test>
</body>
</html>
@lamplightdev
感谢您的回答。
我一直在寻找尚不存在的东西。
所以我选择了一个带有 css var 和 setter 的解决方案来设置它:
class extends HTMLElement {
set content(val) {
this.setAttribute('data-content',val);
}
constructor() {
...
当然还有:
:host::before {
content: attr(data-content);
...
这似乎是我想象中的更简单的解决方案。
我想建议 Web 标准开发人员创建一个新的 css 函数:slot(name) , with attr(...), var (...) 和 calc(...),可以帮助在 Web 组件中使用伪元素。
有人可以告诉我如何提出这个建议吗???
我为我糟糕的英语语言道歉(我是法语,nobdy's perfect)。
好吧,我认为问题在标题中: 在具有 shadowRoot 的 Web 组件中,我想在伪 ::before 或 ::after 元素的内容 属性 中使用插槽 text-content。 这可以让我获得更多台词。
您有想法、建议或解决方案吗?
您可以使用 CSS 自定义属性作为 ::before
和 ::after
的 content
和 slotchange
事件的来源来实现此目的:
<!DOCTYPE html>
<html lang="en">
<head>
<title>WC</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
class XTest extends HTMLElement {
constructor() {
super();
// add shadow dom and insert template content
const shadowRoot = this.attachShadow({ mode: "open" });
const template = document.getElementById("x-test-template");
const templateContent = template.content;
shadowRoot.appendChild(templateContent.cloneNode(true));
}
connectedCallback() {
// get all the named slots
const slots = this.shadowRoot.querySelectorAll("slot[name]");
[...slots].forEach(slot => {
// add a listener to run when the slot changes
slot.addEventListener("slotchange", event => {
// get the slot name
const name = event.target.name;
// get the slot content
const text = event.target.assignedNodes()[0].textContent;
// update the custom property
this.style.setProperty(`--content-${name}`, `'${text}'`);
});
});
}
}
customElements.define("x-test", XTest);
</script>
</head>
<body>
<template id="x-test-template">
<style>
:host {
display: inline-block;
position: relative;
font-size: 2rem;
padding: 2rem;
}
:host::before,
:host::after {
content: "";
position: absolute;
top: 0;
font-size: 1rem;
}
:host::before {
/* set the pseudo selector content to the custom property */
content: var(--content-before, "");
left: 0;
}
:host::after {
/* set the pseudo selector content to the custom property */
content: var(--content-after, "");
right: 0;
}
slot[name] {
display: none;
}
</style>
<!-- slot for ::before -->
<slot name="before"></slot>
<!-- default slot -->
<slot></slot>
<!-- slot for ::after -->
<slot name="after"></slot>
</template>
<x-test>
<span slot="before">B</span>
<span>Hello</span>
<span slot="after">A</span>
</x-test>
</body>
</html>
@lamplightdev
感谢您的回答。
我一直在寻找尚不存在的东西。 所以我选择了一个带有 css var 和 setter 的解决方案来设置它:
class extends HTMLElement {
set content(val) {
this.setAttribute('data-content',val);
}
constructor() {
...
当然还有:
:host::before {
content: attr(data-content);
...
这似乎是我想象中的更简单的解决方案。
我想建议 Web 标准开发人员创建一个新的 css 函数:slot(name) , with attr(...), var (...) 和 calc(...),可以帮助在 Web 组件中使用伪元素。 有人可以告诉我如何提出这个建议吗???
我为我糟糕的英语语言道歉(我是法语,nobdy's perfect)。