可以从 Shadow dom 中导入字体并将其应用于其子项吗?
当尝试做类似的事情时
class MyCustomElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
:host {
font-family: 'Open Sans';
}
</style>
<h1>Hello font?</h1>
`;
}
}
customElements.define('my-custom-element', MyCustomElement);
字体未应用于
<h1>
。 CSS 检查器显示 <h1>
的字体计算为 "Open Sans"
。在网络选项卡中,Chrome 请求样式表,但 Firefox 不请求。在这两种浏览器中,它都以系统默认字体呈现。
要完成这项工作还缺少什么?
完整的 HTML 文件是,
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Font test</title>
</head>
<body>
<script>
class MyCustomElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.innerHTML = `
<style>
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
:host {
font-family: 'Open Sans';
}
</style>
<h1>Hello font?</h1>
`;
}
}
customElements.define("my-custom-element", MyCustomElement);
</script>
<my-custom-element></my-custom-element>
</body>
</html>
火狐
铬
当您在 Shadow DOM 中使用“@import”时,由于应用样式的时间安排,它并不总是按预期工作。 在您的情况下,“@import”规则可能无法及时应用于字体系列声明。
class MyCustomElement extends HTMLElement {
constructor() {
super();
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://fonts.googleapis.com/css?family=Open+Sans';
document.head.appendChild(link);
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
:host {
font-family: 'Open Sans', sans-serif;
}
</style>
<h1>Hello font?</h1>
`;
}
}
customElements.define('my-custom-element', MyCustomElement);
您必须在全局范围和 Web 组件中注册外部字体
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
let href = "https://fonts.googleapis.com/css?family=Open+Sans";
super().attachShadow({mode:'open'})
.innerHTML = `<style>@import url('${href}')</style>` +
`<style>:host{font-family:'Open Sans'}</style>` +
`<h1>Hello Font: </h1>`;
// make sure font is globally loaded
let fontExist =
//document.fonts.check("32px Open Sans");
document.querySelector(`link[href="${href}"]`);
if (!fontExist) {
console.log("append LINK font");
document.head.append(
Object.assign(document.createElement("link"), {
rel: "stylesheet",
href,
onload : () => this.fontloaded()
}))
} else {
this.fontloaded();
}
}
fontloaded(){
let h1 = this.shadowRoot.querySelector("h1");
h1.innerHTML += getComputedStyle(h1).font;
this.hidden = false;
console.log(document.fonts.check('0px Open Sans'));
}
});
</script>
<my-element hidden></my-element>