javascript - 重新附加的 Canvas 元素保留内容

标签 javascript html dom canvas

Parser 是一个能够在目标 Canvas 上绘制 xml 的模块。删除原始 Canvas 元素并附加干净的 Canvas 后, Canvas 将重置,但在进一步重新附加后, Canvas 的内容保持不变。

function setAttributes(elem, attrs) {
  for (var key in attrs) {
    elem.setAttribute(key, attrs[key]);
  }
}

var Parser = (function() {
  var cleanCanvas = (function() {
    var canvas = document.createElement("canvas");
    setAttributes(canvas, {
      "id": "canvas",
      "style": "border: 2px solid black",
      "width": "200px",
      "height": "200px"
    });
    return canvas;
  })();

  return {
    parseSVG: function(data, target) {
      lastTarget = $("#" + target).clone();
      var canvas = document.getElementById(target);
      var ctx = canvas.getContext('2d');

      var DOMURL = window.URL || window.webkitURL || window;

      var img = new Image();
      var svg = new Blob([data], {
        type: 'image/svg+xml;charset=utf-8'
      });
      var url = DOMURL.createObjectURL(svg);

      img.onload = function() {
        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);
      }

      img.src = url;
      var ctx = canvas.getContext('2d');
      var DOMURL = window.URL || window.webkitURL || window;

      var img = new Image();
      var svg = new Blob([data], {
        type: 'image/svg+xml;charset=utf-8'
      });
      var url = DOMURL.createObjectURL(svg);

      img.onload = function() {
        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);
      }

      img.src = url;
    },

    clearCanvas: function() {
      document.body.removeChild(document.getElementById("canvas"));
      document.body.appendChild(cleanCanvas);
    }
  }
})();

//Tried in console:

var data =
  '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
  '<foreignObject width="100%" height="100%">' +
  '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
  '<h1>blah</h1>' +
  '</div>' +
  '</foreignObject>' +
  '</svg>';

//Works properly
Parser.parseSVG(data, "canvas");
Parser.clearCanvas();

//Doesn't work properly
Parser.parseSVG(data, "canvas");
Parser.clearCanvas();
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <canvas id="canvas" style="border: 2px solid black" width="200px" height="200px">
  </canvas>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  <script src="html2img.js"></script>
</body>

</html>

为什么内容保持不变?

最佳答案

cleanCanvas 在任何地方都是相同的引用,具有相同的上下文。这意味着:

// after appending cleanCanvas to body

alert(cleanCanvas === document.getElementById('canvas'));

/* --> true */

您可以将 cleanCanvas 改为一个函数,这样您就可以通过调用它来重新生成它。

var getCleanCanvas = function() {
    var canvas = document.createElement("canvas");

    canvas.id = 'canvas';
    canvas.style.border = '2px solid black';

    setAttributes(canvas, {
        "width": "200px",
        "height": "200px"
    });

    return canvas;
};

现在:

document.body.appendChild(getCleanCanvas());

关于javascript - 重新附加的 Canvas 元素保留内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39306337/

相关文章:

javascript - React Native 中的时刻显示错误的日期

javascript - 单击另一个 select2 下拉列表时如何保持 select2 下拉事件打开

html - 替代使用框架来提供可以通过拖动调整大小的导航区域

javascript - 为什么按价格排序不起作用?

javascript - jQuery 对象后代过滤

Javascript onClick 事件未触发

javascript - 在每个列表中向下滑动

javascript - document.normalize 究竟做了什么?

jquery - 访问动态生成的id

javascript - 如何预测 DOM keydown 是否会导致字符输入