2016-09-03 27 views
1

解析器是一種能夠在目標畫布上繪製xml的模塊。刪除原始畫布元素並添加乾淨畫布後,畫布會重置,但在進一步重新附加後,畫布的內容將保持不變。重新添加的畫布元素保留內容

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>

爲什麼內容保持不變?

回答

0

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()); 
+1

好吧。這工作正常,但屬性不適合你定義的方式,但設置setAttribute是可以的。所以我的cleanCanvas不是一個函數,它只是評估了anonymus函數的返回值,對嗎?這可能會導致我的困惑。 – ntj

+0

@toboR_rM確切地說,但不應該以這種方式定義屬性,一些舊的瀏覽器有時並不處理它們,它們必須使用'id','width'等默認設置器來定義......在HTMLElement中()'。不過,Canvas可以在現代瀏覽器中使用。 – Hydro

+1

我明白了。請記住這一點。 – ntj