Polymer 1.0 - 在ajax响应之后将动态样式应用于自定义元素

时间:2015-10-14 19:37:23

标签: polymer shadow-dom

我有一个自定义元素,它有两类样式,静态和动态。静态样式存在于模块<dom-module><style>...</style></dom-module>中,但动态样式需要存在于自己的样式表中,然后在必要时加载。

自定义元素将具有一些语法color: var(--dynamic-element-color)的样式,然后在一些ajax确定客户端后,我将获取该客户端的样式表并以某种方式包含它以更新mixin样式...可能通过{如果需要,{1}}与@import url(client-1.html)结合使用。

我通过两种方法尝试了这个:

1)在自定义元素的方法中 - 某种形式的这种方法在Chrome中起作用,但在其他地方没有:

Polymer.updateStyles()

2)在index.html中 - 在Chrome和FF中工作但不在Safari或我手机的“互联网”浏览器中工作:

ready: function() {
    this.determineClientStyle('test');
},
determineClientStyle: function(client) {
    var link = document.createElement('link');
    link.rel = 'import';
    link.href = '/elements/'+client+'/linus.html';
    var beforeNode = Polymer.dom(this.root).childNodes[0];
    Polymer.dom(this.root).insertBefore(link, beforeNode);
}

Here is an example project on github.

我的真实项目有很多自定义元素,所有这些元素的样式都带有window.addEventListener('WebComponentsReady', function() { function applyClientTheme(client) { var link = document.createElement('link'); link.rel = 'import'; link.href = client+'.html'; Polymer.dom(document.head).appendChild(link); } applyClientTheme('theme'); }); ,我希望加载一个导入,以便在每个客户端完成所有这些。

我还没有成功完成@Abhinav在下面提到的内容......或者我或者说错误地解释它或者只是做错了。

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:0)

我在这里看到两个问题:

1。样式在页面上泄漏

您不希望自己的风格泄漏到页面上,但很可能您没有使用影子dom,因为从Polymer 1.0开始shady dom是默认设置,不提供样式封装。
您可以通过调整全局聚合物settings来强制聚合物使用阴影dom。

<script>
    window.Polymer = window.Polymer || {};
    window.Polymer.dom = 'shadow';
</script>

2。在shadow dom中使用外部样式表

您可以在shadow dom中使用css @imports来加载外部样式表。 如果页面上有组件以及client标识符,您可以在本地dom中注入这些样式标记。
如果您使用html导入在页面上引入组件,则可以在html中包含一个小脚本,其中包含在模板中注入样式标记的代码。 也许是这样的事情:

//If you are using html imports to bring in your components on page.
//doc will contain html which is being imported.
var doc = document.currentScript.ownerDocument;

// Fetch template from doc
var myTemplate = doc.querySelector('template#myTemplate');
var cssURL = '/elements/'+client+'/dynamic_style_1.css';
// construct a style tag here with css @imports which contain above css url.
// Since you have access to template in myTemplate
// inject this style tag inside it.
// Since it is a css @import, Remember to inject it at top(using insertBefore)

我在这个主题上写了很少的描述性答案herehere 希望它有所帮助。

修改

document.currentScript.ownerDocument会返回当前正在执行 脚本的 文档。

现在,您的组件可能存在两个位置。

  1. 主持人(当前)文件
    在这种情况下,document.currentScript.ownerDocument将返回您可以从中获取模板的当前文档。但是你真的不需要这个,因为你可以直接做一个document.querySelector然后为它添加一个样式标签或做你想做的任何事情。

  2. 导入文件
    现在这很糟糕,因为您的模板不会显示在当前页面上,因此document.querySelector无法抓取您的信息。
    因此,现在有两种方法可以为其添加样式标记,根据您希望执行此操作的 where ,这会有所不同。

  3. <强>一个。就绪方法:当您的客户端标识符存在时,您希望在ready方法中执行此操作。

    很好,您不需要document.currentScript.ownerDocument,因为您只需查询链接标记并使用 import 属性从中获取内容。
    像这样:

    <link id="myImport" rel="import" href="my-components.html">
    
    //This is what goes inside ready method
    var linkTag = document.querySelector('#myImport');
    var importContent = linkTag.import;
    var myTemplate = importContents.querySelector('#myTemplate');
    //Yayy!! You have your template. Now go ahead and inject a style tag into it.
    

    <强>湾导入的HTML:没有!我想在此之前做到这一点。实际上我想在页面上导入我的内容时这样做。

    Okies。你在这里只有选择......等待它......是的,你猜对了。 document.currentScript.ownerDocument
    在HTML导入上引用这个不错的tutorial

      

    进口不在主要文件中。他们是卫星。然而,   您的导入仍然可以在主页面上操作,即使是主页面   文件至高无上。导入可以访问自己的DOM和/或   导入它的页面的DOM。

         

    导入中的脚本引用导入的文档   (document.currentScript.ownerDocument)

    我希望你的用例在于上面提到的三种可能性之一 最后,你的影子根应该包含一个带有css @import的样式标签,它应该指向你的css文件的正确位置。
    如果是这样,则会在页面上加载样式,并在影子根目录中应用