ニシキヘビってかわいいよね、実際みたことないけど。

無職がいよかん国でプログラミングとかの備忘録を書いてます。 一日一食たまごかけごはん。

SVGのプロパティがつかえない時はnamaspaceが設定されているか確認する

こんなHTML(一部分)があって

<div id="svg_wrapper"></div>

動的にSVG要素を用意していた

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

var poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
// 中略
svg.appendChild(poly);

var svg_wrapper = document.getElementById('svg_wrapper');
svg_wrapper.appendChild(svg);

使っているある外部ライブラリに、SVGを構成する文字列を渡すメソッドがあった。
こんな感じに。

extarnal_module.func(svg_wrapper.innerHTML);

ところが処理中に、SVGのpoints属性がないためエラー、とのこと。 内部では渡した文字列をDOMparserでDOMに変換して作業してる模様。

なにがダメだったかというと名前空間が定義されてなかったから。 文字列からSVG要素であるDOMに変換するには事前にルートSVG要素で名前空間を定義してないと、ただのHTMLないしはXMLと解釈されてしまう。

雑にユーティリティ関数作って対処

var createElementSVG = function () {
    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
    svg.setAttributeNS(null, 'version', '1.1');
    return svg;
};

createElementNSからつくったDOMは、ルートSVGタグの名前空間がどうであれ、 そのメソッドの第一引数に渡した名前空間が適用されるためSVGに関わる属性が使える。
あっちでつかえてこっちで使えなかったため、何が原因かわかるのに1日溶かしてしまった。 ああ、情けない。