我有一个自定义元素,它有两类样式,静态和动态。静态样式存在于模块<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在下面提到的内容......或者我或者说错误地解释它或者只是做错了。
这样做的最佳方式是什么?
答案 0 :(得分:0)
我在这里看到两个问题:
您不希望自己的风格泄漏到页面上,但很可能您没有使用影子dom,因为从Polymer 1.0开始shady dom是默认设置,不提供样式封装。
您可以通过调整全局聚合物settings来强制聚合物使用阴影dom。
<script>
window.Polymer = window.Polymer || {};
window.Polymer.dom = 'shadow';
</script>
您可以在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)
我在这个主题上写了很少的描述性答案here和here 希望它有所帮助。
document.currentScript.ownerDocument
会返回当前正在执行 脚本的 文档。
现在,您的组件可能存在两个位置。
主持人(当前)文件
在这种情况下,document.currentScript.ownerDocument
将返回您可以从中获取模板的当前文档。但是你真的不需要这个,因为你可以直接做一个document.querySelector
然后为它添加一个样式标签或做你想做的任何事情。
导入文件
现在这很糟糕,因为您的模板不会显示在当前页面上,因此document.querySelector
无法抓取您的信息。
因此,现在有两种方法可以为其添加样式标记,根据您希望执行此操作的 where ,这会有所不同。
<强>一个。就绪方法:当您的客户端标识符存在时,您希望在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文件的正确位置。
如果是这样,则会在页面上加载样式,并在影子根目录中应用 。