与自定义 HTML 元素共享样式?

2024-03-10

我开始使用自定义元素,但我无法弄清楚的一件事是共享样式。例如,如果我有 2 个自定义元素,<element-1> and <element-2>,两者都包含<button>的,我希望所有按钮都有一定的样式,例如font-size:20px.

我考虑过的选项是:

  1. Use a <stylized-button>自定义元素而不是<button>在自定义元素中。当外部采购时,这是一个问题<element-1>。如果您还想要其他样式(例如color:red)仅在<element-1>按钮而不是<element-2>纽扣。

  2. 据我从聚合物的文档 [1] 得知,聚合物也没有解决方案。

  3. /dead/ and :shadow看起来很有希望,但不再受支持。

  4. 相似地@apply[2]看起来很有希望,但该提案被撤回了。

  5. ::part and ::theme[3] 似乎更有希望,但尚未得到支持。

  6. 使用js支持::part and ::theme[4]。我想如果不解决所有情况的话,这将非常脆弱。

  7. 将共享样式显式添加到每个自定义元素。

     class Element1 extends HTMLElement {
         constructor() {
             this.shadowRoot.addElement(sharedStyle);
         }
     }
    

    这似乎非常受限且手动。还可能影响性能?如果您外部采购也会有问题<element-1>.

现在,我认为 #6 可能是最好的,因为它似乎是最通用/最容易使用的,无需专门为其构建,而且在实现时,它将使过渡到 #5 变得微不足道。但我想知道是否还有其他方法或建议?

[1] https://www.polymer-project.org/3.0/docs/devguide/style-shadow-dom https://www.polymer-project.org/3.0/docs/devguide/style-shadow-dom

[2] http://tabatkins.github.io/specs/css-apply-rule/ http://tabatkins.github.io/specs/css-apply-rule/

[3] https://meowni.ca/posts/part-theme-explainer/ https://meowni.ca/posts/part-theme-explainer/

[4] 一个简单的实现和使用它的示例:https://gist.github.com/mahov/cbb27fcdde4ad45715d2df3b3ce7be40 https://gist.github.com/mahhov/cbb27fcdde4ad45715d2df3b3ce7be40

执行:

document.addEventListener('DOMContentLoaded', () => {
    // create style sheets for each shadow root to which we will later add rules
    let shadowRootsStyleSheets = [...document.querySelectorAll('*')]
        .filter(element => element.shadowRoot)
        .map(element => element.shadowRoot)
        .map(shadowRoot => {
          shadowRoot.appendChild(document.createElement('style'));
          return shadowRoot.styleSheets[0];
        });

    // iterate all style rules in the document searching for `.theme` and `.part` in the selectors.
    [...document.styleSheets]
        .flatMap(styleSheet => [...styleSheet.rules])
        .forEach(rule => {
          let styleText = rule.cssText.match(/\{(.*)\}/)[1];

          let match;
          if (match = rule.selectorText.match(/\.theme\b(.*)/))
            shadowRootsStyleSheets.forEach(styleSheet => styleSheet.addRule(match[1], styleText));
          else if (match = rule.selectorText.match(/\.part\b(.*)/))
            shadowRootsStyleSheets.forEach(styleSheet => styleSheet.addRule(`[part=${match[1]}]`, styleText));
        });
  });

和用法:

<style>
  .my-element.part line-green {
    border: 1px solid green;
    color: green;
  }

  .theme .line-orange {
    border: 1px solid orange;
    color: orange;
  }

  /*
    must use `.part` instead of `::part`, and `.theme` instead of `::theme`
    as the browser prunes out invalid css rules form the `StyleSheetList`'s. 
  */
</style>

<template id="my-template">
  <p part="line-green">green</p>
  <p class="line-orange">orange</p>
</template>

<my-element></my-element>

<script>
  customElements.define('my-element', class extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({mode: 'open'});
      const template = document.getElementById('my-template').content.cloneNode(true);
      this.shadowRoot.appendChild(template);
    }
  });
</script>

您可以使用@import url将外部样式表导入到不同的自定义元素中。

或者现在您也可以使用<link rel="stylesheet">在自定义元素 Shadow DOM 中:

<template id="element-1">
  <style> 
      @import url( 'button-style.css' )
  </style>
  <button>B-1</button>
</template>

<template id="element-2">
  <link rel="stylesheet" href="button-style.css">
  <button>B-2</button>
</template>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与自定义 HTML 元素共享样式? 的相关文章

随机推荐

  • UIResponder 问题

    今晚我一直在与 UIResponder 作斗争 这是我的困境 如果我输入 BOOL canBecomeFirstResponder return YES 到我的 mainViewController 然后我可以获得摇动事件 void mot
  • 无法打开流:是一个目录

    我在尝试使用 php 将上传的文件从临时文件夹移动到所需的文件时收到以下警告 警告 move uploaded file test function move uploaded file 无法打开流 是第 69 行 home filenam
  • MySQL 8 中索引 JSON 列

    所以我正在尝试 json 列 Mysql 8 0 17 应该可以使用多值 JSON 索引 如下所示 CREATE INDEX data nbr idx ON a1 CAST data gt nbr AS UNSIGNED ARRAY 我有像
  • 如何使用 JavaScript 函数验证字段?

    我创建了一个表单 从文档中的示例 https getbootstrap com docs 4 0 components forms在 验证 自定义样式 部分 我在 cumpolsory 输入中添加了 必需 属性 并且验证进展顺利 现在我需要
  • 如何将自定义 Lambda 层包含到管道堆栈中? (AWS-CDK)

    我有两堆 应用栈 管道栈 将自定义 lambda 层包含到管道堆栈中以便将代码位置信息中继回我的应用程序堆栈的官方方法是什么 我已经按照文档使常规 lambdas 工作 在这里找到 https docs aws amazon com cdk
  • ASP.Net MVC Angular 2 最终版

    有人尝试过 Angular 2 RC Final 和 ASP Net MVC 吗 我在使用 ASP Net MVC 配置 Angular 2 RC 6 时遇到问题 直到 beta 17 一切正常 具有以下配置的 package json 似
  • “npm start”导致错误 - ENOENT:没有这样的文件或目录... package.json [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我尝试使用 NPX 创建一个 React 应用程序 一切都很顺利 但是当我跑步时npm start 我收到以下错误 np
  • 如何为 3 组添加一些列值?

    我有 3 列 SAMPN PERNO 循环 以及对应于3种模式的实用程序 角豆和步行 我想添加具有相同 SAMPN PERNO 循环的行的实用程序 适用于 car car bus bus walk walk walk bus 和 Bus w
  • Sqlite 数据库未从 Android 资产文件夹复制

    我正在尝试将名为 adinpect 的数据库从资产文件夹复制到应用程序数据库文件夹 但它不起作用 代码 在主活动 onCreate 中 仅用于测试 try String destPath data data getPackageName d
  • Rails 引擎线程安全 - ActiveResource

    我的 Rails 3 1 应用程序使用一个引擎 我想知道对该引擎的访问是否是线程安全的 我的引擎中有 lib mymodule rb 它看起来像这样 module MyModule def self my method begin data
  • XSLT 递归父/子组合

    非常有趣的Python赏金问题 https stackoverflow com questions 37170543 recursively search for parent child combinations and build tr
  • 识别 Eigen 中的临时对象创建

    正如 Eigen C 库中的文档在许多地方指出的那样 为了在计算时间方面获得最大性能 我们需要尽可能避免临时对象 在我的应用程序中 我处理动态大小矩阵 我想知道在计算中临时矩阵的创建 有没有通用的方法来识别临时矩阵的创建 例如 Eigen
  • opencv imshow with waitKey 在 Mac OS X 10.10.2 上太慢(使用 c++)

    我在 Mac OS X 10 10 2 上使用 opencv c 来处理视频帧并显示它们 使用 waitKey 来显示视频的 imshow 的性能极其缓慢 我有以下代码 它可以正确显示高清 1920x1080 灰度帧 只是它的运行速度慢了大
  • 运行前强制批处理文件加载到 RAM

    我的便携式驱动器的管理分区中有一个批处理文件 驱动器根目录上有一个符号链接到该文件的快捷方式 该文件的目的是卸载驱动器并将其重新安装为指定的盘符 主要是为了方便 打开文件时 它是相对于当前字母而不是卷 ID 打开的 因此自然地 当发生卸载时
  • 如何记住使用 core.async 和非阻塞通道读取的函数?

    我想用memoize对于使用的函数core async and
  • 线程中的类型错误。函数接受 x 位置参数,但给出 y [重复]

    这个问题在这里已经有答案了 我现在正在使用Python 我有一个start function 从消息中获取字符串 我想为每条消息启动线程 目前的线程应该像这样打印出我的消息 def startSuggestworker message pr
  • 如何在没有表单的情况下循环遍历单选按钮组?

    如何在 JavaScript 或 jQuery 中循环访问没有表单的单选按钮组 像这样的事情怎么办 使用 jQuery input radio each function if this is checked You have a chec
  • Apache httpd 与 Tomcat 7:端口 80 与端口 8080

    我最近在 Amazon ec2 上安装了 Tomcat 7 我发现Tomcat默认监听8080端口 互联网上的文档主张这是因为linux更好地将较低的端口保存给超级用户 顺便说一句 ec2 上的解决方案是创建一个负载均衡器 将通信从端口 8
  • 具有多个命名出口的延迟加载模块上的 Angular2 路由

    我在 Angular2 中遇到了路由问题 我的模块是延迟加载的 但到目前为止基本的 loadChildren 方法没有问题 模块本身正在加载 在开发工具的网络选项卡中看到 我的问题 请参阅下面我的路由代码 第一个版本工作正常 当我创建到 的
  • 与自定义 HTML 元素共享样式?

    我开始使用自定义元素 但我无法弄清楚的一件事是共享样式 例如 如果我有 2 个自定义元素