首页 文章

将window.document样式应用于Polymer 2子元素

提问于
浏览
1

我正在开发一个应用程序,用户可以通过拖放来构建网页 . 我们的用户可以删除的一些元素是Polymer2元素 .

用户还可以向其页面添加自定义样式表,如果他们这样做,那里定义的样式应该影响Polymer2元素的子项 .

现在,我知道所有这些都违背了Web组件的行为方式,但我仍然想知道它是否可行 .

我是Polymer的新手,不太确定在哪个方向上看 . 我读过关于mixins,共享样式和自定义样式的内容,但似乎没有一个为我的用例提供有效的方法 .

很感谢任何形式的帮助 .

EDIT

到目前为止,我发现一个解决方案可以工作但不理想,因为 import 将来会被弃用:

/parent-styles.html

<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="parent-styles">
    <link rel="import" type="css" href="ref_to_page_stylesheet.min.css">
</dom-module>

然后我可以导入此文件并使用 <style include="parent-styles"></style> . 这至少允许从页面的样式表中设置Polymer元素的样式,但显然这个解决方案会在样式表名称或位置发生变化时中断,我对此并不满意 .

2 回答

  • 0

    为Web组件设置样式有很多选项 . 使用shadow DOM的组件可以由主页面设置样式,定义自己的样式,或者提供钩子(以CSS自定义属性的形式)以供用户覆盖默认值 .

    要从外部设置组件 <fancy-tabs> 的样式,您可以使用其标记名称作为选择器:

    fancy-tabs {
      width: 350px;
    }
    

    外部样式总是胜过shadow DOM中定义的样式 . 但这只能让你到目前为止 . 如果你想设计 <fancy-tabs> 的内部结构怎么办?这是您必须使用自定义CSS属性创建样式挂钩的地方 .

    例:

    <!-- main page -->
    <style>
      fancy-tabs {
        margin-bottom: 32px;
        --fancy-tabs-bg: black;
      }
    </style>
    <fancy-tabs background>...</fancy-tabs>
    

    <fancy-tabs> 的阴影DOM内:

    :host([background]) {
      background: var(--fancy-tabs-bg, #9E9E9E);
      border-radius: 10px;
      padding: 10px;
    }
    

    在这种情况下,组件将使用黑色作为背景值,因为用户提供了它 . 否则,它将默认为 #9E9E9E .

    使用参考:Shadow DOM v1: Self-Contained Web Components

  • 1

    我自己制定了一些解决方案 . 正如我在问题中已经说过的那样,它有点违背了封装的Web组件哲学 . 它还依赖于将来会被弃用的链接标记 . 最糟糕的是,我还没有进行任何跨浏览器测试......所以:

    USE WITH CAUTION!

    您可以像下面这样使用下面的样式模块(导入后):

    <style include="bb-shared-styles"></style>

    <dom-module id="bb-shared-styles">
      <template id="style-template">
        <style id="stylesheet"></style>
      </template>
    
      <script>
        ((document) => {
          const doc        = (document._currentScript || document.currentScript).ownerDocument;
          const domModule  = doc.querySelector('#bb-shared-styles');
          const template   = doc.querySelector('#style-template');
          const pageStyles = document.styleSheets;
          const styles     = template.content.querySelector('#stylesheet');
          styles.type      = 'text/css';
    
          
          processStyleSheets();
    
          function processStyleSheets () {
            for (let index = 0; index < document.styleSheets.length; index++) {
              const sheet = document.styleSheets[index];
              if (sheet.href) {
                // Prefer adding links to parsing CSS rules for better performance
                appendLink(sheet.href);
              } else {
                const rules = sheet.rules || sheet.cssRules;
                if (rules) {
                  // For inline styles
                  appendRules(rules);
                }
              }
            }
          }
    
          function appendRules (rules) {
            const len = rules.length;
            for (let index = 0; index < len; index++) {
              const rule = rules[index];
              styles.appendChild(document.createTextNode(rule.cssText));
            }
          }
    
          function appendLink (href) {
            let link   = document.createElement('link');
            link.rel   = 'import';
            link.type  = 'css';
            link.href  = href;
            domModule.insertBefore(link, domModule.firstChild);
          }
    
        })(document);
      </script>
    </dom-module>
    

相关问题