CSS 可变槽聚合物(动态加载)元件
CSS Variable trough Polymer (dynamically loaded) elements
我的项目中有多个自定义元素,css 变量有问题。在我的 parent 元素中,我有多个状态为 类 的项目元素。我想使用该状态 类 来操作背景和边框颜色,但我想在我的 parent 元素中定义值,但不知何故它不想工作。
这是我的 parent 元素:
<link rel="import" href="app-task.html" />
<dom-module id="app-task-grid">
<template>
<style>
:host {
display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%;
overflow:hidden; background: #eee;
--column-1-width: 80px;
--column-3-width: 120px;
--column-4-width: 180px;
--column-5-width: 220px;
--column-6-width: 100px;
--task-background-color: #eee;
--task-border-color: #ccc;
}
:host table.header {
position: absolute; top: 0; left: 0; width: 100%; height: 40px; background: #DDD;
}
:host table.header th {
letter-spacing: 2px; font-weight: normal; text-transform: uppercase;
font-size: 80%; border-left: 1px solid #aaa;
margin: 0; padding: 0 10px;
}
:host th.column1 {
width: var(--column-1-width);
}
:host th.column2 {
text-align: left;
}
:host th.column3 {
width: var(--column-3-width);
}
:host th.column4 {
width: var(--column-4-width);
}
:host th.column5 {
width: var(--column-5-width);
}
:host th.column6 {
width: var(--column-6-width);
text-align: left;
}
:host th.hide, :host td.hide {
display: none;
}
:host th.show, :host td.show {
display: table-cell;
}
:host table.header .scrollbar {
width: 20px; border-left: none;
padding: 0;
}
:host .items {
position: absolute; left: 0; top: 40px; right: 0; bottom: 0;
overflow:hidden; overflow-y: scroll;
margin: 0; padding: 0;
}
:host .items::-webkit-scrollbar {
width:22px; border-left: 6px solid #ddd;
background-color:#ddd;
}
:host .items::-webkit-scrollbar-thumb {
background-color:#aaa;
border-left: 6px solid #ddd;
min-height: 80px;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<table class="header">
<tr>
<th class="column1"></th>
<th class="column2">Column#2</th>
<th class="column3">Column#3</th>
<th class="column4">Column#4</th>
<th class="column5">Column#5</th>
<th class="column6">Column#6</th>
<th class="scrollbar"></th>
</tr>
</table>
<div class="items">
<app-task id="task0" class="waiting"></app-task>
</div>
</template>
<script>
Polymer({
is:"app-task-grid",
loadItems: function()
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
this.querySelector('.items').appendChild( itemElement );
}
}
});
</script>
</dom-module>
我的children元素:
<dom-module id="app-task">
<template>
<style>
:host {
display: block; margin: 8px 0; padding: 0;
}
:host table {
width: 100%; height: 80px;
background-color: var(--task-background-color, #fff);
border-bottom: 5px solid var(--task-background-color, #fff);
border-top: 5px solid var(--task-background-color, #fff);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.07),
0 1px 5px 0 rgba(0, 0, 0, 0.06),
0 3px 1px -2px rgba(0, 0, 0, 0.1);
}
:host table td {
border-left: 1px solid var(--task-border-color, #ccc);
margin: 0; padding: 0 10px;
}
:host td.column1 {
width: var(--column-1-width);
}
:host td.column2 {
}
:host td.column3 {
width: var(--column-3-width);
}
:host td.column4 {
width: var(--column-4-width);
}
:host td.column5 {
width: var(--column-5-width);
}
:host td.column6 {
width: var(--column-6-width);
}
</style>
<table>
<tr>
<td class="column1">C#1</td>
<td class="column2">C#2</td>
<td class="column3">C#3</td>
<td class="column4">C#4</td>
<td class="column5">C#5</td>
<td class="column6">C#6</td>
</tr>
</table>
</template>
<script>
Polymer({
is:"app-task"
});
</script>
</dom-module>
我已经试过了:
- :host .waiting { ... }
- :host app-task.waiting { ... }
- app-task.正在等待{ ... }
- :root .waiting { ... }
- :root app-task.waiting { ... }
- :root { .waiting { ... } }
- :root { app-task.waiting { ... } }
- parent 元素为 app-task 为 类
- 样式是="custom-style" 在app-grid 模板中
- style is="custom-style" 在模板外但在 app-grid 元素内 html 文件
但其中 none 似乎有效。
如果我在 :host 中定义 css 变量,那么它就可以工作,只是不能以某种方式与 类 一起工作。哪里弄错了?
更新#1:
如果我将 "style-scope app-task-grid" 添加到任务的 parent 元素中,style-scope 会出现一些奇怪的问题:
<div class="items">
<div class="style-scope app-task-grid waiting">
<app-task id="task1"></app-task>
</div>
</div>
然后,如果我添加一个正常的 css 规则,例如它在 app-task 中应用的颜色,但 css 变量不是。
更新#2:
因为有人提到这个模板是有效的,我测试了它,它是,!但 id 没有提到项目是动态创建并附加到项目的。我在 Plunker 上添加了我的代码中的几乎所有内容:http://plnkr.co/edit/b5XW1w3sEOy4UHc0rdWH?p=preview
对不起我的误导,我不知道问题根源是动态负载。
注意:我用更多示例更新了问题。
更新#3:
感谢@a1626s 和@GünterZöchbauer,我们找到了答案:
我的初始代码很好,从一开始就可以工作,我定义问题很糟糕,因为我没有看到问题所在。因此,如果有人在元素内部动态加载元素,则必须使用 Polymer.dom api.
Polymer.dom(this.querySelector('.items')).appendCild(itemElement);
请记住,设置 CSS 变量的 <style>
必须在标记中包含 is="custom-style"
。
我拼凑了一个非常粗略的片段来展示它。
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
另一个例子运行通过几个元素
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<dom-module id="app-task-grid">
<template>
<!-- normal styles -->
<style>
app-task {
width: 50%;
margin: 10px auto;
}
</style>
<!-- custom styles -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
</template>
<script>
Polymer({
is: 'app-task-grid'
});
</script>
</dom-module>
<!-- And now pushing it to the screen -->
<app-task-grid></app-task-grid>
我没有发现您的初始代码有任何问题。我复制了您的代码并将其粘贴到 plunker
<style>
:host {
display: block;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
它对我来说似乎工作正常。
至于你的新问题,用这个方法替换你的 javascript
方法,它应该可以工作。
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
Polymer.dom(this.$.items).appendChild(itemElement);
}
Polymer.dom.flush();
}
此外,这是我在您的 app-task-grid
元素中所做的更改
<div class="items" id="items"> //added id attribute to the div tag
问题在于您添加子元素的方式无法将它们正确插入到元素的 dom tree
中。 Polymer 有关于如何使用其元素树的文档。您可以阅读更多相关信息 here
我的项目中有多个自定义元素,css 变量有问题。在我的 parent 元素中,我有多个状态为 类 的项目元素。我想使用该状态 类 来操作背景和边框颜色,但我想在我的 parent 元素中定义值,但不知何故它不想工作。
这是我的 parent 元素:
<link rel="import" href="app-task.html" />
<dom-module id="app-task-grid">
<template>
<style>
:host {
display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%;
overflow:hidden; background: #eee;
--column-1-width: 80px;
--column-3-width: 120px;
--column-4-width: 180px;
--column-5-width: 220px;
--column-6-width: 100px;
--task-background-color: #eee;
--task-border-color: #ccc;
}
:host table.header {
position: absolute; top: 0; left: 0; width: 100%; height: 40px; background: #DDD;
}
:host table.header th {
letter-spacing: 2px; font-weight: normal; text-transform: uppercase;
font-size: 80%; border-left: 1px solid #aaa;
margin: 0; padding: 0 10px;
}
:host th.column1 {
width: var(--column-1-width);
}
:host th.column2 {
text-align: left;
}
:host th.column3 {
width: var(--column-3-width);
}
:host th.column4 {
width: var(--column-4-width);
}
:host th.column5 {
width: var(--column-5-width);
}
:host th.column6 {
width: var(--column-6-width);
text-align: left;
}
:host th.hide, :host td.hide {
display: none;
}
:host th.show, :host td.show {
display: table-cell;
}
:host table.header .scrollbar {
width: 20px; border-left: none;
padding: 0;
}
:host .items {
position: absolute; left: 0; top: 40px; right: 0; bottom: 0;
overflow:hidden; overflow-y: scroll;
margin: 0; padding: 0;
}
:host .items::-webkit-scrollbar {
width:22px; border-left: 6px solid #ddd;
background-color:#ddd;
}
:host .items::-webkit-scrollbar-thumb {
background-color:#aaa;
border-left: 6px solid #ddd;
min-height: 80px;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<table class="header">
<tr>
<th class="column1"></th>
<th class="column2">Column#2</th>
<th class="column3">Column#3</th>
<th class="column4">Column#4</th>
<th class="column5">Column#5</th>
<th class="column6">Column#6</th>
<th class="scrollbar"></th>
</tr>
</table>
<div class="items">
<app-task id="task0" class="waiting"></app-task>
</div>
</template>
<script>
Polymer({
is:"app-task-grid",
loadItems: function()
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
this.querySelector('.items').appendChild( itemElement );
}
}
});
</script>
</dom-module>
我的children元素:
<dom-module id="app-task">
<template>
<style>
:host {
display: block; margin: 8px 0; padding: 0;
}
:host table {
width: 100%; height: 80px;
background-color: var(--task-background-color, #fff);
border-bottom: 5px solid var(--task-background-color, #fff);
border-top: 5px solid var(--task-background-color, #fff);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.07),
0 1px 5px 0 rgba(0, 0, 0, 0.06),
0 3px 1px -2px rgba(0, 0, 0, 0.1);
}
:host table td {
border-left: 1px solid var(--task-border-color, #ccc);
margin: 0; padding: 0 10px;
}
:host td.column1 {
width: var(--column-1-width);
}
:host td.column2 {
}
:host td.column3 {
width: var(--column-3-width);
}
:host td.column4 {
width: var(--column-4-width);
}
:host td.column5 {
width: var(--column-5-width);
}
:host td.column6 {
width: var(--column-6-width);
}
</style>
<table>
<tr>
<td class="column1">C#1</td>
<td class="column2">C#2</td>
<td class="column3">C#3</td>
<td class="column4">C#4</td>
<td class="column5">C#5</td>
<td class="column6">C#6</td>
</tr>
</table>
</template>
<script>
Polymer({
is:"app-task"
});
</script>
</dom-module>
我已经试过了:
- :host .waiting { ... }
- :host app-task.waiting { ... }
- app-task.正在等待{ ... }
- :root .waiting { ... }
- :root app-task.waiting { ... }
- :root { .waiting { ... } }
- :root { app-task.waiting { ... } }
- parent 元素为 app-task 为 类
- 样式是="custom-style" 在app-grid 模板中
- style is="custom-style" 在模板外但在 app-grid 元素内 html 文件
但其中 none 似乎有效。
如果我在 :host 中定义 css 变量,那么它就可以工作,只是不能以某种方式与 类 一起工作。哪里弄错了?
更新#1:
如果我将 "style-scope app-task-grid" 添加到任务的 parent 元素中,style-scope 会出现一些奇怪的问题:
<div class="items">
<div class="style-scope app-task-grid waiting">
<app-task id="task1"></app-task>
</div>
</div>
然后,如果我添加一个正常的 css 规则,例如它在 app-task 中应用的颜色,但 css 变量不是。
更新#2:
因为有人提到这个模板是有效的,我测试了它,它是,!但 id 没有提到项目是动态创建并附加到项目的。我在 Plunker 上添加了我的代码中的几乎所有内容:http://plnkr.co/edit/b5XW1w3sEOy4UHc0rdWH?p=preview
对不起我的误导,我不知道问题根源是动态负载。
注意:我用更多示例更新了问题。
更新#3:
感谢@a1626s 和@GünterZöchbauer,我们找到了答案:
我的初始代码很好,从一开始就可以工作,我定义问题很糟糕,因为我没有看到问题所在。因此,如果有人在元素内部动态加载元素,则必须使用 Polymer.dom api.
Polymer.dom(this.querySelector('.items')).appendCild(itemElement);
请记住,设置 CSS 变量的 <style>
必须在标记中包含 is="custom-style"
。
我拼凑了一个非常粗略的片段来展示它。
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
另一个例子运行通过几个元素
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<dom-module id="app-task-grid">
<template>
<!-- normal styles -->
<style>
app-task {
width: 50%;
margin: 10px auto;
}
</style>
<!-- custom styles -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
</template>
<script>
Polymer({
is: 'app-task-grid'
});
</script>
</dom-module>
<!-- And now pushing it to the screen -->
<app-task-grid></app-task-grid>
我没有发现您的初始代码有任何问题。我复制了您的代码并将其粘贴到 plunker
<style>
:host {
display: block;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
它对我来说似乎工作正常。
至于你的新问题,用这个方法替换你的 javascript
方法,它应该可以工作。
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
Polymer.dom(this.$.items).appendChild(itemElement);
}
Polymer.dom.flush();
}
此外,这是我在您的 app-task-grid
元素中所做的更改
<div class="items" id="items"> //added id attribute to the div tag
问题在于您添加子元素的方式无法将它们正确插入到元素的 dom tree
中。 Polymer 有关于如何使用其元素树的文档。您可以阅读更多相关信息 here