CSS可以逃脱阴影dom(Polymer)吗?

时间:2014-08-18 22:45:14

标签: javascript css polymer web-component

我在Polymer中有一个下拉元素。由于z索引问题,我需要将下拉部分拉出来并使其成为<body>的直接子项。不幸的是,我无法弄清楚如何做到这一点,仍然能够实际设计元素的样式。我能想出的唯一解决方案是将下拉部分作为自己的聚合物标签,但这似乎真的......倒退了。

简而言之,我有一个元素:

<my-element>
    <template>
        <style>...</style>

        <input>
        <div id="dropdown">...</div>
    </template>
</my-element>

然后在执行document.body.appendChild( this.$.dropdown )

的元素中使用JS

我正在试图弄清楚如何移动下拉菜单,但是Polymer / Web Components的CSS隔离阻止了我这样做。

1 个答案:

答案 0 :(得分:1)

[edit]请注意,聚合物无法正确处理通过DOM使用此方法附加的on-*事件处理程序,因为它无法将DOM树移回聚合物元素。所以事件需要手动附加到使用它的任何东西。

我创建了一个可以插入任何元素的自定义元素,它会提取所有以body开头的规则,并将它们提升为插入head的新样式表。还有一些工作要做,特别是需要进行polyfilled的浏览器,因为::shadow选择器不起作用。但我很快就会谈到这一点。

<link rel="import" href="../polymer/polymer.html" />
<polymer-element name="promote-body-css">
    <script>
        'use strict';

        ~function(){
            var promoted = {};

            function promote( node ){
                var nodeName = node.nodeName;

                if( promoted[ nodeName ] ){ return; }

                var promoteRules = [];

                [].forEach.call( node.querySelectorAll( '::shadow style' ), function( stylesheet ){
                    [].forEach.call( stylesheet.sheet.cssRules, function( rule ){
                        if( rule.cssText.indexOf( 'body ' ) === 0 ){
                            promoteRules.push( rule.cssText );
                        }
                    } );
                } );

                if( promoteRules.length ){
                    var stylesheet = document.createElement( 'style' );
                    stylesheet.innerHTML = promoteRules.join( '' ) + '/* Inserted from polymer element ' + nodeName + ' */';

                    document.getElementsByTagName( 'head' )[0].appendChild( stylesheet );
                }
            }

            promoted[ nodeName ] = 1;

            Polymer( 'promote-body-css', {
                attached : function( parent ){
                    promote( ( parent = this.parentNode ).host || parent );
                }
            } );
        }();
    </script>
</polymer-element>