如何避免在更改容器的innerHtml时清除canvas元素

时间:2012-08-23 19:04:45

标签: javascript html5 canvas innerhtml

我使用javascript绘制到div中的canvas元素,包含在包装器中。 canvas和它的div是通过添加到包装器的innerHTML动态生成的。 目标是允许生成无限数量的画布

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
     <!-- infinite # of container divs & canvases -->
</div>

然而,当我向包装器的innerHTML添加一个新的div和canvas时,任何绘制到前一个画布的东西都会丢失。

如果我在页面的其他位置添加新画布,在容器外部的div或容器的子项中添加:

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
</div>
<div id="wrapper2">
     <!-- newly inserted canvas: -->
     <div id="container"><canvas></canvas></div>
</div>

或:

<div id="wrapper">
     <div id="container"><canvas id="previous"></canvas></div>
     <div id="wrapperChild">
          <!-- newly inserted canvas: -->
          <div id="container"><canvas></canvas></div>
     </div>
</div>

然后保留上一个画布。

从我可以告诉我更改包装器的innerHTML或它的父母导致清除画布。关于如何避免清除画布的任何建议?我可以保留在其他地方绘制的画布并恢复它吗?

4 个答案:

答案 0 :(得分:4)

无论你的javascript方法(jQuery,别的什么,或什么都没有),你可以通过不使用innerHTML来做到这一点。基本上,当你附加到innerHTML属性时,你会说“获取innerHTML的值,将它添加到这个新值(也许是canvas元素),然后将innerHTML设置为所有这些。换句话说,你不是'你真的附加了“就地”。你基本上是在添加你拥有的所有东西的新版本,并且因为画布没有用子元素绘制它的内容,所以它们不会被这种方法带来。

您应该使用DOM而不是使用innerHTML,将子节点作为节点而不是字符串附加到父节点。

答案 1 :(得分:0)

听起来这是jQuery的一个很好的用例。使用jquery,您可以将<canvas>元素附加到任意容器中,并避免与“innerHtml”进行交互。

例如:

var myCanvas = $("<canvas>").appendTo("#container");

这样做是为id为“container”(你的div)的元素添加一个新的<canvas>元素。 “#”是ids的css选择器。谷歌“css选择器”,因为这是一个相当广泛的主题。

myCanvas变量现在是一个jQuery数组,其中包含对刚刚添加的画布的引用。 myCanvas[0]将是您可以与之交互的实际DOM元素。

使用这种方法,您永远不需要更改div的“innerHtml”,因此永远不会触及/清除现有的画布。

答案 2 :(得分:0)

使用appendChild:

,而不是使用innerHtml
document.getElementById('wrapper').appendChild(NewNodeHere);

答案 3 :(得分:-2)

查看Simon关于绘制形状的教程。 http://simonsarris.com/project/canvasdemo/shapes.html

形状的所有属性和位置都存储在对象数组中。 当事件发生时(单击形状)画布的状态发生变化(在这种情况下,正在拖动一个形状),并且对于鼠标位置的每次更改,都会使用新的坐标和属性重绘画布。

现在,如果您还使用形状,图像,文本对象,也可以将它们的属性存储在对象数组中。这样,只需多次遍历数组,就可以以相同的方式在多个画布上绘制相同的形状。

因此,当您动态添加新画布时,您只需重绘上一个上下文。

这是Simon教程中的相关代码:

定义矩形形状(构造函数)

function Shape(x, y, w, h, fill) {
  this.x = x || 0;
  this.y = y || 0;
  this.w = w || 1;
  this.h = h || 1;
  this.fill = fill || '#AAAAAA';
}

将此形状绘制到给定的上下文中     Shape.prototype.draw = function(ctx){        ctx.fillStyle = this.fill;        ctx.fillRect(this.x,this.y,this.w,this.h);     }

向数组添加新形状

CanvasState.prototype.addShape = function(shape) {
  this.shapes.push(shape);
  this.valid = false;
}

遍历数组并相应地绘制所有形状

var l = shapes.length;
for (var i = 0; i < l; i++) {
  var shape = shapes[i];
  // We can skip the drawing of elements that have moved off the screen:
  if (shape.x > this.width || shape.y > this.height ||
      shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
  shapes[i].draw(ctx);
}