【问题标题】:Polymer 1.0 - Apply dynamic style to custom element after ajax responsePolymer 1.0 - 在 ajax 响应后将动态样式应用于自定义元素
【发布时间】:2015-10-14 19:37:22
【问题描述】:

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

自定义元素将具有一些样式,语法为 color: var(--dynamic-element-color),然后在一些 ajax 内容确定客户端后,我将获取该客户端的样式表并以某种方式包含它以更新 mixin 样式...也许通过 @import url(client-1.html)必要时结合Polymer.updateStyles()

我通过两种方法进行了尝试:

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

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);
}

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

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');
});

Here is an example project on github.

我的真实项目有许多自定义元素,所有这些元素都将具有var(--some-style) 的样式,我希望加载一个单一的导入来满足每个客户的要求。

@Abhinav 在下面提到的内容我还没有成功......要么我解释不正确,要么只是做错了。

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

【问题讨论】:

    标签: polymer shadow-dom


    【解决方案1】:

    我在这里看到两个问题:

    1。页面样式泄露

    您不希望您的样式泄漏到页面上,但很可能您没有使用 shadow 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 返回文档其中脚本当前正在执行。

    现在,您的组件可能存在于 2 个地方。

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

    2. 导入的文档
      现在这很糟糕,因为您的模板不在当前页面上,所以document.querySelector 无法获取您。
      所以,现在有两种方法可以给它附加一个样式标签,这将根据你想要执行此操作的哪里而有所不同。

    一个。 Ready 方法: 当您的客户端标识符存在时,您希望在 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.
    

    b.导入的 HTML: 不!我什至想在那之前做。实际上,我想在页面上导入我的内容时这样做。

    好吧。你在这里唯一的选择是......等待它......是的,你猜对了。 document.currentScript.ownerDocument.
    在 HTML 导入中引用这个漂亮的 tutorial

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

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

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

    【讨论】:

    • 我不遵循您的描述性答案。您能否提供一些关于如何将附加样式表注入自定义元素的具体代码?
    • 我已经用代码 sn-p 更新了我的答案。 Here 是另一个答案,如果需要,它会提供更多详细信息。
    • 你能看看我在问题中更新的代码 sn-p 并告诉我这是否是正确的地方和方法吗?此 ready 方法属于将使用样式的自定义元素。此外,我可以看到 style 被添加为 myTemplate 的子节点,但我并不肯定,这就是我想要的。
    • 我还注意到,如果自定义元素代码位于单独的文件中并正在导入,则 document.currentScript.ownerDocument 不起作用。
    • 您上次的编辑是我建议的。它奏效了吗?我已根据您对 document.currentScript.ownerDocument 的查询更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2012-06-27
    相关资源
    最近更新 更多