我正在测试Polymer开发一个我想在html中重复使用多次的组件(见下图)。我开发了以下元素:
<link rel="import" href="bower_components/polymer/polymer.html">
<script src="js/fabric.js"></script>
<dom-module id="tooth-element">
<template>
<style>
#labelWrapper {
display: flex;
justify-content: center;
align-items: center;
font-size: 35px;
font-weight: bold;
height: 40PX;
}
</style>
<div id="toothWrapper">
<div id="upperRootWrapper">
<canvas id="upperRoot" />
</div>
<div>
<canvas id="tooth" />
</div>
<div id="lowerRootWrapper">
<canvas id="lowerRoot" />
</div>
<div id="labelWrapper">
<p>{{toothLabel}}</p>
</div>
</div>
</template>
<script>
var TOOTH_SIZE = 50;
var TOOTH_GAP = 5;
var UPPERROOTID = 'upperRoot';
var LOWERROOTID = 'lowerRoot';
var TOOTHID = 'tooth';
Polymer({
is: "tooth-element",
properties: {
// declare the owner property
showUpperRoot: {
type: Boolean,
value: true
},
showLowerRoot: {
type: Boolean,
value: true
},
toothLabel: {
type: String,
value: 30
}
},
ready: function() {
drawUpperRoot(this.showUpperRoot);
drawTooth();
drawLowerRoot(this.showLowerRoot);
initLabel(this.toothLabel);
}
});
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
function drawUpperRoot (isVisible) {
var canvas = new fabric.Canvas(UPPERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP);
canvas.renderAll();
canvas.add(drawFace(1));
} else {
document.getElementById("upperRootWrapper").style.display = "none";
}
}
function drawTooth () {
var canvas = new fabric.Canvas(TOOTHID);
canvas.setHeight(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(2));
canvas.add(drawFace(3));
canvas.add(drawFace(4));
canvas.add(drawFace(5));
canvas.add(drawFace(6));
//canvas.add(drawFace(7));
}
function drawLowerRoot (isVisible) {
var canvas = new fabric.Canvas(LOWERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(7));
} else {
document.getElementById("lowerRootWrapper").style.display = "none";;
}
}
function drawFace(face) {
var coordinates;
switch (face) {
case 1:
coordinates = getFace1Coordinates();
break;
case 2:
coordinates = getFace2Coordinates();
break;
case 3:
coordinates = getFace3Coordinates();
break;
case 4:
coordinates = getFace4Coordinates();
break;
case 5:
coordinates = getFace5Coordinates();
break
case 6:
coordinates = getFace6Coordinates();
break;
case 7:
coordinates = getFace7Coordinates();
break;
default:
coorddinates = null;
}
face = new fabric.Polygon(coordinates, {
fill: '#E1E1E1',
selectable: false,
stroke: 'green'
});
face.on('mousedown', function () {
if (face.fill == '#E1E1E1') {
face.fill = '#878787';
} else {
face.fill = '#E1E1E1';
}
});
return face;
}
function getFace1Coordinates() {
return [{x: TOOTH_SIZE, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE}, {x: 0, y: TOOTH_SIZE}];
}
function getFace2Coordinates() {
return [{x: 0, y: TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: 0, y: TOOTH_SIZE*3}];
}
function getFace3Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
function getFace4Coordinates() {
return [{x: TOOTH_SIZE*3+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3}];
}
function getFace5Coordinates() {
return [{x: 0, y: TOOTH_SIZE*3+TOOTH_GAP}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3+TOOTH_GAP}];
}
function getFace6Coordinates() {
return [{x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2}];
}
function getFace7Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
</script>
</dom-module>
我正试图在index.html文件中导入它:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="tooth-element.html">
</head>
<body>
<div id="line1">
<tooth-element></tooth-element>
<tooth-element></tooth-element>
</div>
</body>
</html>
当我在div line1中放置两个tooth-elements时会出现问题。永远不会显示第二个元素,因为从不为它调用ready函数。我不知道为了解决这个问题我应该做些什么。任何帮助将不胜感激
我想在html中重复的组件布局如下所示(我得到第一个牙齿元素的图像,但不是第二个牙齿元素):
(溶液) 我没有正确使用DOM(正如Neil John Ramal所解释的那样)。使用Glenn和Neil建议使用Poly.dom API我能够得到我想要的行为
答案 0 :(得分:1)
在处理本地DOM(即document.getElementById
,document.querySelector
等)时,请避免使用常规DOM API。请改用Polymer.dom
。请注意,当您将Polymer设置为使用Shadow DOM而不是Shady DOM时,您的代码可能会失败,因为常规DOM访问器无法穿透Shadow DOM(封装是其功能之一,Shady DOM尝试近似)。
代码中的一个问题是结果元素与某些全局对象紧密耦合(例如drawUpperRoot
)。这实际上打破了元素封装,因为这个代码也将被该元素的其他实例使用,这样你就不会使用自己的范围,而是基本上使它们依赖于全局范围。
此代码:
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
意味着当你创建两个tooth-element
时,第二个元素基本上会引用第一个元素labelWrapper
而不是它自己的A
。
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html
答案 1 :(得分:1)
document.querySelector()返回它在文档中找到的第一个元素,第二个元素被忽略。
将文档更改为此应解决问题。
document.querySelector('#labelWrapper') -> this.querySelector(#labelWrapper)
或者
document.querySelector('#labelWrapper') -> Polymer.dom(this).querySelector('#labelWrapper')