如何为分布式内容设置自定义CSS属性

时间:2015-12-31 16:19:49

标签: dart dart-polymer

我正在尝试设置作为内容传递的PaperMenu节点的自定义CSS属性。
--paper-menu-background-color:green;适用于主文档,或者当PaperMenu是我的自定义组件的一部分且不在distributedNodes()中时。

我有以下main.html

<html>
<head>
  <meta charset="utf-8">
  <link rel="import" href="packages/polymer_elements/paper_menu_button.html">
  <link rel="import" href="packages/polymer_elements/paper_menu.html">
    <link rel="import" href="packages/polymer_elements/paper_submenu.html">
  <link rel="import" href="packages/polymer_elements/paper_item.html">
  <link rel="import" href="packages/polymer_elements/paper_icon_button.html">
  <link rel="import" href="packages/polymer_elements/paper_badge.html">
  <link rel="import" href="packages/my_p/my_menu_bar.html">
</head>
<body unresolved>
<my-menu-bar>
    <paper-menu>
        <paper-submenu>
            <paper-item class="menu-trigger">Topics</paper-item>
            <paper-menu raised class="menu-content">
                <paper-item>Topic 1</paper-item>
                <paper-item>Topic 2</paper-item>
                <paper-item>Topic 3</paper-item>
            </paper-menu>
        </paper-submenu>
    </paper-menu>
</my-menu-bar>
  <script type="application/dart" src="index.dart"></script>
  <script src="packages/browser/dart.js"></script>
</body>
</html>

我不希望main.html中的以下内容有效:

<style is="custom-style">
     :root{--paper-menu-background-color:green;}
</style>

my_menu_bar.html

<dom-module id="my-menu-bar">
  <style>
    :host ::content paper-menu{
      display:inline-block;
      top:0;
      vertical-align: text-top;
    --paper-menu-background-color:green;
    <!--Does not work, setting colors via script-->
    }

  </style>

  <template>
    <div id='my_menu_bar_div'>
    <content></content>
    </div>
  </template>
</dom-module>

下面的css生效但不是'--paper-menu-background-color:green;'

  

显示:内联块;顶部:0; vertical-align:text-top;

通过dart脚本和反射设置背景颜色:

@HtmlImport('my_menu_bar.html')
library m_p.lib.my_menu_bar;
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'package:polymer_elements/paper_input.dart';
import 'package:polymer_elements/paper_menu.dart';
import 'package:polymer_elements/paper_submenu.dart';
import 'package:polymer_elements/paper_item.dart';
import 'dart:async';
import 'package:web_components/web_components.dart';
import 'dart:mirrors';


@PolymerRegister('my-menu-bar')
class MyMenuBar extends PolymerElement {
  MyMenuBar.created() : super.created() { }
  void _recursive_set_style(var e, String attrName, String value){
//    print(reflect(e).type.superclass.toString());
    if(!(reflect(e).type.isSubtypeOf(reflectClass(HtmlElement))))
      return;
//    print('ya, it\'s subtype of HtmlElement');
    InstanceMirror helperMirror = reflect(e.style);
    var methodsAr  = helperMirror.type.instanceMembers;
    var sym = new Symbol(attrName);
    print(methodsAr[sym]);
    if(null !=methodsAr[sym]){
      helperMirror.setField(sym,value);
    }
    for(var ie in e.children){
      _recursive_set_style(ie,attrName,value);
    }
   }

  attached() {
    super.attached();
    new Future(() {
      ContentElement ce = Polymer.dom(this.root)
          .querySelector('content');
      PolymerDom dom = Polymer.dom(ce);
      List<Node> nodes = dom.getDistributedNodes();
      nodes.removeWhere((n)=>!(n is PaperMenu));
      //Setting colors
      updateStyles();
      for(var e in nodes){
        _recursive_set_style(e,'backgroundColor','rgb(156, 58, 53)');
      }
    });
  }
}

我个人喜欢用css编写脚本,但是很想知道这样做的标准方法以及为什么会这样。

修改

感谢GünterZöchbauer的评论,该功能现已缩减为:

void _recursive_set_style(var e, String attrName, String value){
    e.attributes[attrName]=value;
    for(var ie in e.children){
      _recursive_set_style(ie,attrName,value);
    }
  }

至于包装内容标签,它没有用,或者我还在做些傻事。

EDIT2

嗨,GünterZöchbauer。
如果你可以帮我确认一下,那就太好了。
任何事情都很难确定 我的菜单栏:

<dom-module id="my-menu-bar">
  <style>
    :host ::content paper-menu{
      display:inline-block;
      top:0;
      backgroundColor:black;
      --paper-menu-background-color:green;
      vertical-align: text-top;
    }
    :host ::content .special{
      <!--setting class name did nothing-->
      display:inline-block;
      top:0;
      backgroundColor:black;
      --paper-menu-background-color:green;
      vertical-align: text-top;
    }
    :host div#my_menu_bar ::content paper-menu{
      --paper-menu-background-color:green;
    }
    :host #my_menu_bar_div > ::content paper-menu{
      --paper-menu-background-color:green;
    }
    :host #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
    }
    #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
    }
    ::content paper-menu{
      --paper-menu-background-color:green;
    }
    paper-menu{
      --paper-menu-background-color:green;
    }
    :root ::content paper-menu{
      --paper-menu-background-color:green;
    }
    :root #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
    }
    :host ::content .paper-menu{
      --paper-menu-background-color:green;
    }
    :host ::content #paper-menu{
      --paper-menu-background-color:green;
    }

  </style>

  <template>
    <style>
      :host ::content paper-menu{
      display:inline-block;
      top:0;
      backgroundColor:black;
      --paper-menu-background-color:green;
      vertical-align: text-top;
      }
      :host ::content .special{
      <!--setting class name did nothing-->
      display:inline-block;
      top:0;
      backgroundColor:black;
      --paper-menu-background-color:green;
      vertical-align: text-top;
      }
      :host div#my_menu_bar ::content paper-menu{
      --paper-menu-background-color:green;
      }
      :host #my_menu_bar_div > ::content paper-menu{
      --paper-menu-background-color:green;
      }
      :host #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
      }
      #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
      }
      ::content paper-menu{
      --paper-menu-background-color:green;
      }
      paper-menu{
      --paper-menu-background-color:green;
      }
      :root ::content paper-menu{
      --paper-menu-background-color:green;
      }
      :root #my_menu_bar_div ::content paper-menu{
      --paper-menu-background-color:green;
      }
      :host ::content .paper-menu{
      --paper-menu-background-color:green;
      }
      :host ::content #paper-menu{
      --paper-menu-background-color:green;
      }
    </style>
    <div id='my_menu_bar_div'>
    <content></content>
    </div>
  </template>
</dom-module>

我尝试了调试器,似乎CSS变量sham和相关值在initPolymer()和标准CSS指令(如“display:inline-block;”)之前生效。

EDIT3

嗨,GünterZöchbauer。 为了回应你的“这看起来不对。”,我仔细检查了一下。 但我认为css变量假是值得责备的。我的意思是,正如我先说的那样,标准的CSS指令正在处理分布式内容。

  

在shady DOM下,<content>标记不会出现在DOM树中。   重写样式以删除:: content伪元素,以及任何   组合器紧靠:: content。

的左侧

描述有点缺乏,但是从示例中我假设它告诉我在:: content伪元素的右侧和左侧有选择器,我想我总是那么正确。
深入挖掘需要javascript知识而且我没有这个,我知道javascript是web的基础,但我不是网络程序员,并且想要在潜水之前覆盖广泛,所以我会放弃这个。

<dom-module id="my-menu-bar">

  <template>
    <style>
      :host .content-wrapper > ::content div{
        /* These CSS variables do not work*/
        --paper-menu-background-color:blue;
        --paper-item{
          background-color:red;
        }
        /*The below works alright*/
        /*background-color:green;*/
        /*color:red;*/
      }
      :host .content-wrapper > ::content .special{
        /* This and the above should have
        the same scope of selection, but this one
        does not work at all.
        Encapsulation playing a trick idk.*/
        /*background-color:green;*/
        /*color:red;*/
      }
      :host ::content div{
        /*works*/
        /*background-color:green;*/
      }
      :host ::content {
      /* does not work*/
        /*background-color:green;*/
      }

      :host ::content paper-menu{
        /*works but custom property and color*/
        /*color:blue;*/
          display:inline-block;
          top:0;
          vertical-align: text-top;
      }
      :host ::content paper-item{
        /*works*/
        /*color:blue;*/
      }
    </style>
    <div class='content-wrapper'>
    <content></content>
    </div>
  </template>
</dom-module>

Edit4

经过漫长而徒劳的搜索,我相信我找到了它。

http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/?redirect_from_locale=pt

  

关于插入点在概念上奇怪的是它们没有   物理移动DOM。主机节点保持不变。插入点   只是将节点从主机重新投影到阴影树中。它是   演示/渲染事物:“将这些节点移到这里”“渲染   这个位置的这些节点。“

You cannot traverse the DOM into a <content>.

如果我可以从阴影dom中为外部灯光dom设置CSS变量的值,那将破坏封装。虽然Color等属于内容伪元素,但css变量和mixin是将值插入css占位符的宏。

1 个答案:

答案 0 :(得分:0)

要在shady DOM(默认)中使用此工作,您需要将<content>标记包装在另一个标记中,并将此包装器包含在选择器中。 请参阅https://www.polymer-project.org/1.0/docs/devguide/styling.html#styling-distributed-children-content(第一个示例了解更多详情) 如果这仍然不起作用,则可能是CSS变量垫片的限制。

<dom-module id="my-element">
  <template>
    <style>
      /* styling elements distributed to content (via ::content) requires */
      /* selecting the parent of the <content> element for compatibility with */
      /* shady DOM . This can be :host or a wrapper element. */
      .content-wrapper > ::content .special {
        background: orange;
      }
    </style>
    <div class="content-wrapper"><content></content></div>
  </template>
</dom-module>