如何使用shadow DOM在动态加载的Web组件样式中加载@font-face

2024-01-10

我有一个带有 Shadow DOM 的 HTML 5 WebComponent,它显示的内容必须根据组件中显示的内容类型加载样式。样式表列表是从服务器获取的。

我可以像这样加载样式表:

for (const style of styles) {
    const stylesheet = document.createElement('link');
    stylesheet.setAttribute('rel', 'stylesheet');
    stylesheet.setAttribute('href', style);
    stylesheet.setAttribute('type', 'text/css');
    this.root.appendChild(stylesheet);
}

然而,样式表有时还包括@font-face规则,这些规则不会添加到组件中。浏览器永远不会创建对字体引用的请求@font-face规则。如何动态加载这些规则?


原来浏览器不支持loading@font-face自 2020 年 9 月起,CSS 在影子 DOM 中占据主导地位。不过,Chrome 团队似乎正在努力解决这个问题。

我采取的方法是寻找@font-face动态创建的样式表中的规则,稍微修改它们以使相对路径正常工作,然后将它们添加到<head>带有脚本的页面。如果您添加@font-face规则到头andShadow DOM,字体将被加载和应用。

这是代码:

for (const style of styles) { // styles is an array of urls
    const stylesheet = document.createElement('link');
    stylesheet.setAttribute('rel', 'stylesheet');
    stylesheet.setAttribute('href', style);
    stylesheet.setAttribute('type', 'text/css');
    stylesheet.onload = (event) => {
        for (
            let i = 0;
            i < event.currentTarget.sheet.cssRules.length;
            i++
        ) {
            if (event.currentTarget.sheet.cssRules[i].type == 5) { // type 5 is @font-face
                const split = style.split('/');
                const stylePath = split
                    .slice(0, split.length - 1)
                    .join('/');
                let cssText =
                    event.currentTarget.sheet.cssRules[i].cssText;
                cssText = cssText.replace(
                    // relative paths
                    /url\s*\(\s*[\'"]?(?!((\/)|((?:https?:)?\/\/)|(?:data\:?:)))([^\'"\)]+)[\'"]?\s*\)/g,
                    `url("${stylePath}/$4")`
                );

                const st = document.createElement('style');
                st.appendChild(document.createTextNode(cssText));
                document
                    .getElementsByTagName('head')[0]
                    .appendChild(st);
            }
        }
    };
    this.root.appendChild(stylesheet);
}

它在 Edge 85(基于 Chromium)上运行良好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用shadow DOM在动态加载的Web组件样式中加载@font-face 的相关文章

  • 我可以使用 jQuery 动态创建文件(及其内容)吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 这是我的 HTML 代码 ul li
  • HTML 上传 MAX_FILE_SIZE 似乎不起作用

    我想知道隐藏字段是如何命名的MAX FILE SIZE应该工作吗
  • Javascript 考虑 colspan 和 rowspan 获取表格单元格二维数组

    我有一个带有 colspan 和 rowspan 的表 如下所示 5x3 表 table tr td 1 td td 2 td td 3 td td 4 td tr tr td 5 td td 6 td td 7 td tr tr td 8
  • 具有自定义设计的 ASP.NET 复选框

    有没有办法改变asp net复选框的ui样式 我试过这个 cabeceraCheckBoxNormal background url ig res Default images ig checkbox off gif no repeat c
  • 在 HTML 中,

    应该以哪种方式嵌套?

    是否有更正确的嵌套顺序 a and h1 HTML 中的元素 e g a href www example com h1 Example h1 a or h1 a href www example com Example a h1 在 HT

  • Safari 不触发表单提交

    对于一个项目 我有两个选择表单字段 它们通过 jquery 触发器 提交 发送 这在 Firefox 和 Chrome 中运行良好 但在 Safari 中没有任何反应 这是 HTML 代码
  • Socket.io 如何判断某人何时离开

    我正在使用 socket io 创建一个实时游戏 目前 当有人离开时 什么也不会发生 我想以某种方式通知服务器说谁离开了 有没有办法在用户离开时发出正确的信息 我可以让服务器每 1000 毫秒对每个人执行一次 ping 操作 或者通过其他方
  • 使用 JQuery 更改表附加行中某些单元格的背景颜色

    我正在向表中追加一行 如何更改该行中一组单元格的背景颜色 假设列有 25 列 从 17 到 22 的列需要更改背景颜色 这是我到目前为止所尝试的 table1 append row1 row1 children td not td eq 0
  • (IE 特定)如何确定输入的文本是否比输入元素的宽度长

    这是所有版本 IE 特有的问题 在所有其他浏览器中 当文本溢出时 输入元素的scrollWidth 大于输入元素的clientWidth 有没有办法确定IE中输入字段中的文本超出了输入元素宽度的键 下面是一个检查 clientWidth 与
  • 使用他们的 API 创建一个基本的 MailChimp 注册表单

    我是 MailChimp 的新手 需要一些帮助 通过他们的基本时事通讯注册表单 您只需将一些预先打包的 HTML 嵌入到您的页面中即可 然而 这样做的问题是 单击 提交 会重定向到 MailChimp 页面 我不想重定向到 MailChim
  • HTML 选择框,从 servlet 中选择数据

    再会 我在 html 中的选择框上遇到问题 我位于简单 CRUD 项目的编辑部分 在用户可以编辑之前 将首先显示所选数据 然后我通过 servlet 在数据库中检索它 现在我希望我检索的数据成为我的选择框中选定的数据 默认 product
  • 将整个网页设计为 SVG 文件

    免责声明 我意识到鉴于标题的荒谬 这听起来像一个巨魔 然而 这是一个真正的问题 我的背景涉及OpenGL x86 汇编 我最近开始学习网络编程 我真的很喜欢 SVG CSS 并且想知道 为什么人们不使用 SVG 设计整个网页 Context
  • 在文档片段中查找注释或文本节点

    我必须清理 Nokogiri HTML DocumentFragment 文档 删除仅包含空格的注释节点和文本节点 这是一个例子 html p paragraph p p paragraph p p paragraph p doc Noko
  • 将 DIV 堆叠在一起?

    是否可以堆叠多个 DIV 例如 div div div div div div div div div div 那么所有这些内部 DIV 都具有相同的 X 和 Y 位置吗 默认情况下 它们都在彼此下方 将 Y 位置增加了上一个 DIV 的高
  • 为什么我的字体大小在 android webview 对象中看起来比在 android 浏览器中查看时大得多?

    我正在尝试制作一个小型 Android 应用程序 它除了在 webview 对象而不是浏览中显示网站之外什么也不做 到目前为止它加载了目标网页 但文本和图像大小都比查看页面时大得多在实际设备浏览器中 在浏览器中 页面看起来正确 但在我的应用
  • 如何在没有查询参数的情况下重新加载页面?

    假设我想重新加载www domain com abc num 4 但我想重新加载www domain com abcONLY 问号后没有所有内容 window location window location href split 0
  • App_offline.htm、CSS、图像和 aspnet_isapi.dll

    因此 我正在开发的网站正在使用 urlrewriting 与 aspnet isapi dll 配合 所有内容都映射到它 我放置了 app offline htm 文件 所有文本均显示 但是 CSS 或图像未提供 我猜测由于通配符映射而不是
  • 如何防止 CSS 或 jQuery 中单词和标点符号之间的换行

    我在一个段落中有一些文字 我的问题是 当标点符号位于单词末尾时 有时可以换行到下一行 像这样 This is the text This is a new line 我可以用 CSS 或 jQuery 解决这个问题吗 如果您不在单词和标点符
  • 插入四个空格而不是制表符

    我试图在按下 Tab 键时插入四个空格 我正在使用以下代码 请参阅spaces t 但是当我将其切换到spaces 当我按 Tab 时只插入一个空格 我还尝试了 function textarea keydown function e va
  • 使用 CSS 屏蔽图像

    我做了这样的设计 如何用CSS遮盖背景 我试过这样的代码 img poster display block max width 100 webkit mask image url https cdn pbrd co images GYiCo

随机推荐

  • 为什么 ControlCollection 不抛出 InvalidOperationException?

    继这个问题用于处理跳过迭代的控件的 Foreach 循环 https stackoverflow com questions 35083873 foreach loop for disposing controls skiping iter
  • 循环展开和优化

    给定代码 for int i 0 i lt n i A i B i C i 以及优化版本 for int i 0 i lt n 2 i 3 A i A i 1 A i 2 B i B i 1 B i 2 C i C i 1 C i 2 我不
  • 用python检测并记录声音

    我正在使用这个程序在 python 中录制声音 在 Python 中检测和录制音频 https stackoverflow com questions 892199 detect record audio in python 892293
  • 在同一应用程序中为不同屏幕制作可重用的表格视图的最佳方法是什么?

    我正在快速开发一个类似于 Instagram 的社交 iOS 应用程序 我有两个屏幕 其中包含几乎相同的提要显示 第一个是包含表格视图的简单提要屏幕 第二个是包含个人资料信息的表格视图标题的个人资料屏幕 并且表格视图应包含第一个屏幕的相同数
  • 如何在sql中连接具有相同id的多行?

    我的表包含两个字段的详细信息 ID DisplayName 1 Editor 1 Reviewer 7 EIC 7 Editor 7 Reviewer 7 Editor 19 EIC 19 Editor 19 Reviewer 我想通过 D
  • 有没有办法将 Python/Tkinter 连接到已经运行的 Tcl/Tk 应用程序?

    我在 Pure Data 上做了很多工作 这是一个用 Tcl Tk 和 C 编写的应用程序 我希望能够为修改 Tcl Tk GUI 的插件制作一个 python API 为此 我似乎需要能够将正在运行的 Tk 实例传递给 python 然后
  • 将预构建的 APK 添加到 Android AOSP system.img

    我正在从源代码构建 AOSP 我想做的是在生成的 system img 中包含一些预构建的文件 作为 make 过程的一部分 我试图找到创建 system img 的实际文件并在其中添加几行 任何想法 先感谢您 将自定义文件添加到的好方法s
  • 连字符、下划线或驼峰命名法作为 URI 中的单词分隔符?

    我正在为 Intranet 应用程序设计一个基于 HTTP 的 API 我意识到这在宏伟的计划中只是一个很小的问题 但是 我应该使用连字符 下划线或驼峰命名法来分隔 URI 中的单词吗 以下是我的初步想法 骆驼香烟盒 如果服务器不区分大小写
  • 在 C++ Set 和 Vector 中取消引用迭代器时出错

    我正在编写这段代码 但收到此错误 错误 将 const std vector 作为 void std vector push back const value type 的 this 参数传递 with Tp metastock7 Allo
  • 仅从 Chrome 扩展程序安全访问 api

    我正在努力允许 Chrome 扩展通过发布数据向我的网站发布新条目 我希望能够将其锁定 以便只有 chrome 扩展可以发布 如果我从其他地方获取发布数据 我想拒绝它 有谁知道这是否 如何可能 或者你将如何去做 不幸的是 从 Web 服务器
  • 为 Matplotlib 创建默认值集

    我经常为自己的研究制作绘图 所有默认设置都很好 但经常必须切换到为演讲 演示设计绘图 我手动设置所有字体大小大一点 http www mailinglistarchive com html matplotlib users lists so
  • Elixir `mix` 命令抛出错误`无法调用 Module.put_attribute/3,因为模块 Helloworld.MixProject 已编译`

    使用命令设置新项目mix new project name它设置了一切 没有任何 错误或警告消息 cd 到项目并运行命令iex S mix它抛出错误 lib helloworld ex defmodule Helloworld do mod
  • “暂停”被忽略

    我读到我必须能够使用单个命令运行站点中的所有单元测试 因此我创建了一个 bat 文件来执行此操作 即使在结束前暂停 在 phpunit 命令之后 单元测试的结果也会在屏幕中闪烁 echo off cd c cd xampp cd htdoc
  • 访问 Android Wear Fit 数据

    我正在 Samsung Gear Live Google I O 版 上开发一款适用于 Android Wear 的应用程序 它将需要访问心率和步数历史数据 我知道稍后可以使用以下方式访问这些数据谷歌健身 SDK https develop
  • Android中如何获取当前SIM卡号码?

    我想知道 Android 中的用户手机号码 我使用了这个代码 但我没有得到号码 TelephonyManager tm TelephonyManager getSystemService Context TELEPHONY SERVICE
  • mysql 和 30 天

    我正在一个处理免费订阅的网站上工作 我现在想知道如何在 30 天不活动后取消订阅 我知道这必须通过 cron jobs 完成 但我不知道如何在 30 天后计数用户上次登录的时间 SELECT user id FROM users WHERE
  • Visual Studio Code 环绕

    我找不到任何方法可以在 VS Code 中用某些内容包围所选内容 For example doing something like that text gt text just by selecting the word text and
  • jq:错误:无法用字符串索引数组

    我正在尝试为检查点管理服务器 API 编写 bash 脚本 但遇到了一些问题 我想获取 json 字典中的值 为此我必须使用变量 我正在输入这个命令 echo rulebase jq arg n 0 rulebase n to 我收到下一个
  • 阻止浏览器重新发送 post 变量

    当用户尝试登录我的网站时 他的用户名和密码将作为 POST 变量发送 当页面加载时 我获取变量 处理它们并决定登录是否成功 然后 我呈现包含一条消息的页面 通知用户登录成功或失败 我的问题是 如果用户按 F5 或刷新 浏览器会提示他们重新发
  • 如何使用shadow DOM在动态加载的Web组件样式中加载@font-face

    我有一个带有 Shadow DOM 的 HTML 5 WebComponent 它显示的内容必须根据组件中显示的内容类型加载样式 样式表列表是从服务器获取的 我可以像这样加载样式表 for const style of styles con