(see problem in action)我的问题一般是 - 我可以使用innerHTML添加元素,我可以设置它们的样式。但我不能将addEventListeners添加到他们身上=(有没有人看到过这样的问题?(see how it worked before I added html generation)
所以我有这么简单的Javascript:
function $(id) {
return document.getElementById(id);
}
/* ------------------------------------------------ */
var POINTS = $('points');
var W = 800, W1_2 = W / 2;
var H = 410, H1_2 = H / 2;
var FPS = 20, FRAMES = 0;
var str ="";
var CV = $('canvas');
var CX = CV.getContext('2d');
CV.width = W;
CV.height = H;
function reCoord(){
// coort = $('coor');
// coort.innerHTML = str;
}
/* ------------------------------------------------ */
var id = 0;
var Draggable = function(PointParams, x, y, callbacks) {
var elementIdSring;
var t = this;
switch (PointParams) {
case 'point':
POINTS.innerHTML += '<div id="p' + id + '" class="point"></div>';
elementIdSring = 'p'+String(id);
break;
case 'cp1':
POINTS.innerHTML += '<div id="p' + id + '" class="point cp1"></div>';
elementIdSring = 'p'+String(id);
break;
case 'cp2':
POINTS.innerHTML += '<div id="p' + id + '" class="point cp2"></div>';
elementIdSring = 'p'+String(id);
break;
case 'limiter':
POINTS.innerHTML += '<div id="l' + id + '" class="point limiter"></div>';
elementIdSring = 'l'+String(id);
break;
}
id++;
coort = $('coor');
coort.innerHTML += elementIdSring + ' ';
var e = $(elementIdSring);
t.element = e;
t.callbacks = {
begin: function() {},
end: function() {},
drag: function() {}
};
if (callbacks != null) for (var v in callbacks) {
switch (v) {
case 'begin':
case 'end':
case 'drag':
if (callbacks[v] instanceof Function)
t.callbacks[v] = callbacks[v];
break;
}
}
t.move(x, y);
var e = $(elementIdSring);
e.addEventListener('mousedown', function(ev) {
if (ev.which == 1) {
Draggable.Target = [t,
t.x - ev.clientX,
t.y - ev.clientY];
t.callbacks.begin();
ev.preventDefault();
ev.stopPropagation();
}
}, false);
};
Draggable.prototype.move = function(x, y) {
reCoord();
var s = this.element.style;
s.left = (this.x = x) + 'px';
s.top = (this.y = y) + 'px';
};
Draggable.tracking = function(ev) {
var t = Draggable.Target;
str = 'X : ' +ev.clientX + ', ' + 'Y :' + ev.clientY ;
if (t) {
t[0].move(ev.clientX + t[1], ev.clientY + t[2]);
t[0].callbacks.drag();
}
};
Draggable.finish = function(ev) {
var t = Draggable.Target;
if (t) {
t[0].move(ev.clientX + t[1], ev.clientY + t[2]);
t[0].callbacks.end();
coort = $('coor');
coort.innerHTML = " ";
Draggable.Target = null;
}
};
window.addEventListener('mousemove',
Draggable.tracking, false);
window.addEventListener('mouseup',
Draggable.finish, false);
/* ------------------------------------------------ */
var linePoints = [
new Draggable('point', 50, 175),
new Draggable('cp1', 175, 225),
new Draggable('cp2', 175, 120),
new Draggable('point', 350, 120),
new Draggable('point', 370, 175),
new Draggable('cp1', 475, 225),
new Draggable('cp2', 475, 175),
new Draggable('point', 650, 165),
new Draggable('point', 50, 275) ,
new Draggable('cp1', 175, 225),
new Draggable('cp2', 175, 325),
new Draggable('point', 350, 325),
new Draggable('point', 370, 275) ,
new Draggable('cp1', 475, 225),
new Draggable('cp2', 475, 275),
new Draggable('point', 650, 285)
];
var Limits = [
new Draggable('limiter', 50, 150),
new Draggable('limiter', 650, 150),
new Draggable('limiter', 50, 300) ,
new Draggable('limiter', 650, 300)
];
/* ------------------------------------------------ */
window.addEventListener('mousemove',
Draggable.tracking, false);
window.addEventListener('mouseup',
Draggable.finish, false);
var MODE = 1;
function line(p0, p1, p2, p3, t) {
return [(1 - t) * p0.x + t * p3.x,
(1 - t) * p0.y + t * p3.y];
}
function quadratic(p0, p1, p2, p3, t) {
var s = 1 - t;
return [s*s*p0.x + 2*s*t*p1.x + t*t*p3.x,
s*s*p0.y + 2*s*t*p1.y + t*t*p3.y];
}
function bezier(p0, p1, p2, p3, t) {
var s = 1 - t;
return [s*s*s*p0.x + 3*s*s*t*p1.x +
3*s*t*t*p2.x + t*t*t*p3.x,
s*s*s*p0.y + 3*s*s*t*p1.y +
3*s*t*t*p2.y + t*t*t*p3.y];
}
function catmull(p0, p1, p2, p3, t) {
var v = [(p2.x - p0.x)/2, (p2.y - p0.y)/2];
var w = [(p3.x - p1.x)/2, (p3.y - p1.y)/2];
return [(2*p1.x-2*p2.x+v[0]+w[0])*t*t*t +
(-3*p1.x+3*p2.x-2*v[0]-w[0])*t*t +
v[0]*t + p1.x,
(2*p1.y-2*p2.y+v[1]+w[1])*t*t*t +
(-3*p1.y+3*p2.y-2*v[1]-w[1])*t*t +
v[1]*t + p1.y];
}
/* ------------------------------------------------ */
var TYPE = $('type');
TYPE.addEventListener('change', redraw, false);
function drawArrow(type, t, P0, P1, P2, P3) {
var c, c0, c1;
c0 = window[type](P0, P1, P2, P3, t - 0.1);
c = window[type](P0, P1, P2, P3, t);
c1 = window[type](P0, P1, P2, P3, t + 0.1);
CX.save();
CX.translate(c[0], c[1]);
CX.rotate(Math.atan2(c1[1] - c0[1], c1[0] - c0[0]));
CX.beginPath();
CX.moveTo(0, 0);
CX.lineTo(-10, 10);
CX.lineTo(-10, -10);
CX.closePath();
CX.stroke();
CX.restore();
}
function locLiner(P0start,P3end, color){
CX.strokeStyle = color;
CX.beginPath();
CX.moveTo(P0start.x, P0start.y);
CX.lineTo(P3end.x, P3end.y);
CX.stroke();
}
function locBesier(P0start, cp1, cp2, P3end){
CX.strokeStyle = '#000';
CX.beginPath();
CX.moveTo(P0start.x, P0start.y);
CX.bezierCurveTo(cp1.x, cp1.y,
cp2.x, cp2.y,
P3end.x, P3end.y);
CX.stroke();
CX.strokeStyle = '#ccc';
CX.beginPath();
CX.moveTo(P0start.x, P0start.y);
CX.lineTo(cp1.x, cp1.y);
CX.lineTo(cp2.x, cp2.y);
CX.lineTo(P3end.x, P3end.y);
CX.stroke();
}
function locQuadratic(P0start, cp1, P3end){
CX.strokeStyle = '#000';
CX.beginPath();
CX.moveTo(P0start.x, P0start.y);
CX.quadraticCurveTo(cp1.x, cp1.y,
P3end.x, P3end.y);
CX.stroke();
CX.strokeStyle = '#ccc';
CX.beginPath();
CX.moveTo(P0start.x, P0start.y);
CX.lineTo(cp1.x, cp1.y);
CX.lineTo(P3end.x, P3end.y);
CX.stroke();
}
function redraw() {
var type = TYPE.value, i, c, c0, c1, t, d;
CX.setTransform(1,0, 0,1, 0,0);
CX.clearRect(0, 0, W, H);
CX.setTransform(1,0, 0,1, -10,-10);
for(i =0; i<Limits.length; i=i+2){locLiner(Limits [i], Limits[i+1], '#FF0000');}
CX.strokeStyle = '#000';
CX.beginPath();
switch (POINTS.className = type) {
case 'line':
for(i =0; i<linePoints.length; i=i+4){locLiner(linePoints[i], linePoints[i+3], '#000');}
break;
case 'quadratic':
for(i =0; i<linePoints.length; i=i+4){locQuadratic(linePoints[i], linePoints[i+1], linePoints[i+3]);}
break;
case 'bezier':
for(i =0; i<linePoints.length; i=i+4){locBesier(linePoints[i], linePoints[i+1], linePoints[i+2], linePoints[i+3]);}
break;
default:
return;
}
for(i =3; i<linePoints.length; i=i+16){locLiner(linePoints[i], linePoints[i+1]); CX.beginPath();
CX.strokeStyle = '#000000';
CX.fillStyle = '#38A1DB';
CX.moveTo(linePoints[i].x,linePoints[i].y);
CX.bezierCurveTo(linePoints[i].x , (linePoints[i].y +( linePoints[i+1].y - linePoints[i].y)/2), linePoints[i+1].x, (linePoints[i].y +( linePoints[i+1].y - linePoints[i].y)/2), linePoints[i+1].x,linePoints[i+1].y);
CX.bezierCurveTo(linePoints[i+1].x , (linePoints[i+1].y +( linePoints[i+8+1].y - linePoints[i+1].y)/2), linePoints[i+8+1].x, (linePoints[i+1].y +( linePoints[i+8+1].y - linePoints[i+1].y)/2), linePoints[i+8+1].x,linePoints[i+8+1].y);
CX.bezierCurveTo(linePoints[i+8+1].x , (linePoints[i+8+1].y +( linePoints[i+8].y - linePoints[i+8+1].y)/2), linePoints[i+8].x, (linePoints[i+8+1].y +( linePoints[i+8].y - linePoints[i+8+1].y)/2), linePoints[i+8].x,linePoints[i+8].y);
CX.bezierCurveTo(linePoints[i+8].x , (linePoints[i+8].y +( linePoints[i].y - linePoints[i+8].y)/2), linePoints[i].x, (linePoints[i+8].y +( linePoints[i].y - linePoints[i+8].y)/2), linePoints[i].x,linePoints[i].y);
CX.fill();
}
CX.strokeStyle = '#39B7CD';
for (i = 0; i < 100; i += 10) {
for(j =0; j<linePoints.length; j=j+4){ drawArrow(type, (i + FRAMES % 10) / 100, linePoints[j], linePoints[j+1], linePoints[j+2], linePoints[j+3]);}
}
++FRAMES;
}
setInterval(redraw, 1500 / FPS);
和一些html:
<canvas id="canvas"></canvas>
<div id="points"></div>
<p id="coor"></p>
<select id="type">
<option value="line">line</option>
<option value="quadratic">quadratic</option>
<option value="bezier" selected>bezier</option>
</select>
和一些CSS:
@charset "UTF-8";
/* ------------------------------------------------ */
HTML,BODY,OL,UL,LI,DL,DT,DD,P,DIV,SPAN {
margin:0;
padding:0;
}
/* ------------------------------------------------ */
BODY {
margin:10px;
background:#eee;
color:#000;
}
#canvas {
background:#fff;
}
.point {
position:absolute;
width:9px;height:9px;
margin:-4px 0 0 -4px;
background:rgba(0, 0, 255, 0.5);
border:rgba(128, 128, 255, 0.8);
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
}
.limiter{
border:rgba(128, 1, 1, 0.8);
background:rgba(255, 1, 1, 0.5);
}
.line .cp1, .line .cp2
{
display:none;
}
.quadratic .cp2{
display:none;
}
.quadratic .cp1,
.bezier .cp1,
.bezier .cp2
{
background:rgba(0, 255, 0, 0.5);
border:rgba(128, 255, 128, 0.8);
}
答案 0 :(得分:1)
为什么不通过innerHTML将元素的创建切换为类似
的元素var el=document.createElement("DIV");
el.style.property="value";
el.addEventListener(myFunction, bubbleFlag);
POINTS.appendChild(el);
答案 1 :(得分:1)
POINTS.innerHTML +=
不要那样做。
将POINTS
的整个DOM内容序列化为HTML字符串,添加新字符串,并将连接的字符串重新解析为POINTS
元素中所有内容的新元素。除了速度慢之外,它还会丢失元素之前内容中的所有不可序列化信息,例如表单字段值,事件侦听器和JS引用。
与kstrieder的答案一样,使用DOM操作。