Dynamically inject shared styles in polymer elemen

2019-05-10 17:54发布

问题:

I do have several nested polymer elements created by myself. Currently with using polymers shared styles I'm able to inject custom styling into other elements. Unfortunately this approach is restricted to static use. So at implementation time I do need to know which Element should use which shared style by import the shared style module with <link rel="import" href="my-shared-style.html"> and <style include="my-shared-style"></style>.

But in my use case I do need to inject shared styles into polymer elements at runtime. Is there any possibility to achieve this?

UPDATE

I tried following approach inspired by Günters answer below:

Polymer({
    is : 'html-grid-row',
    /**
    * Inject style into element
    * @param {string} style
    */
    injectStyle : function(style) {
        var customStyle = document.createElement('style', 'custom-style');
        customStyle.textContent = style;
        Polymer.dom(this.root).appendChild(customStyle);
    }
    /**
    * Additional Elements JS functionality is put here...
    *
    */
)}

When I now try to dynamically add style by calling injectStyle('div {font-weight: bold;}') on elements instance at runtime the style module is injected into the element but is not displayed because polymer seems to edit custom-styles text content like the following:

<style is="custom-style" class="style-scope html-grid-row">
    div:not([style-scope]):not(.style-scope) {font-weight: bold;}
</style>

Is there a way to prevent polymer from adding the :not([style-scope]):not(.style-scope) prefix to style rules?

UPDATE 2:

Referencing a global shared style using include='my-shared-style' does have the same effect.

Include this shared style which is statically imported globally using html import:

<dom-module id="my-shared-style">
    <template>
        <style>
            div {
                font-weight: bold;
            }
        </style>
    </template>
</dom-module>

After dynamically import and referencing shared-style Polymer includes following:

<style is="custom-style" include="my-shared-style" class="style-scope 
 html-grid-row">
    div:not([style-scope]):not(.style-scope) {
        font-weight: bold;
    }
</style> 

SOLUTION

Finally I used a workaround for dynamically inject styling into Polymer elements at runtime by extending the <style> HTML Element with document.register('scoped-style', {extends : 'style', prototype : ...}). The injectStyle(style) method (see above) now creates a <style is="scoped-style"> element directly as child of the Elements root node. Indeed it's inspired by https://github.com/thomaspark/scoper. This works so far for me.

回答1:

I used something like this successfully to inject styles dynamically

var myDomModule = document.createElement('style', 'custom-style');
myDomModule.setAttribute('include', 'mySharedStyleModuleName');
Polymer.dom(sliderElem.root).appendChild(myDomModule);

The style-module 'mySharedStyleModuleName' needs to be imported somewhere (like index.html).

See also https://github.com/Polymer/polymer/issues/2681 about issues I run into with this approach and https://stackoverflow.com/a/34650194/217408 for more details