SVGをcreateElementするには「NS」が必要。

〽️ NSとは名前空間のこと。 〽️ 名前空間とは? 〽️ なぜcreateElementはダメなのか?




⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。





syntax。


let svg1 = document.「「1createElementNS」」("http://www.w3.org/2000/svg","svg");


createElement( )では動かない。


こんにちは、「ふ」です。

HTMLにおいてSVGを扱うときには、<img>で外部参照する、または<body>内に直接SVGコードを記述することが多いかと思います。
しかし時として、

 「何らかのタイミングやきっかけに応じて、<svg>要素を生成して表示」

というように、JavaSctiptを使って動的にSVGを生成したい場合もあるでしょう。


〜ここで通常のHTML要素であれば、

let p_elm = document.createElement("「「1p」」");

で装うことができます.. しかし。


let svg_elm = document.createElement("「「4svg」」");  「「4//無効」」

これは、動きません💧
SVGをcreateElementするには、createElementNS( )メソッドを使って名前空間を提示する必要があります。



今回は、

についてお伝えしていきます。

SVG生成において、名前空間が必要となる「背景の部分」からしっかりと理解して、webサイト制作に役立ててください。

createElementNSの使いかた。



document.「「2createElemenNS(「「5"名前空間名"」」,「「5"要素名"」」)」」

createElemetNSの「NS」は、name-space(名前空間)を指しています。
第1引数には生成する要素の名前空間名、第2引数には生成する要素名を記述します。

さっそくHTMLの中でSVG要素を生成してみましょう。
その配置場所である<div>領域を準備しました。

<div id = "area"> </div>

#area { width:20em; height:15em; margin:0 auto; }



何も入っていない<div>要素を作りました。
JavaScriptで<svg>を生成し、ここに追加します。

「「3//親要素のdivを取得 ..①」」 const area = document.getElementById("area"); 「「3//SVG要素を生成 ..②」」 let svg1 = document.「「2createElementNS(「「5"http://www.w3.org/2000/svg"」」,「「5"svg"」」)」」; 「「3//大きさと背景色を追加 ..③」」 svg1.setAttribute("width","80%"); svg1.setAttribute("height","80%"); svg1.style.backgroundColor = "beige"; 「「3//親要素に追加 ..④」」 area.appendChild(svg1);


① 親要素の「#area」を取得。

② createElementNSを使って、<svg>を生成します。
第1引数にはSVGの名前空間名である「http://www.w3.org/2000/svg」を指定。

③ 結果をプレビューしやすいように、width/heightと背景色を付けました。

④ 親要素の「#area」に生成した<svg>を追加します。

<svg>要素を生成し、<div>要素の中に追加することができました。

子要素もしかり。


SVGの子要素を生成するときにも、createElementNSを使う必要があります。
今の<svg>要素の中に、<circle>(円オブジェクト)を作って配置してみましょう。

「「3//円オブジェクトを生成」」 let circle1 = document.「「2createElementNS(「「5"http://www.w3.org/2000/svg"」」,「「5"circle"」」);」」 「「3//位置と半径、塗りを指定」」 circle1.setAttribute("cx","50%") circle1.setAttribute("cy","50%"); circle1.setAttribute("r","20%"); circle1.setAttribute("fill","darkgreen"); 「「3//SVG領域に追加」」 svg1.appendChild(circle1);

ここでもSVGの名前空間を指定して、円オブジェクトを生成します。
位置やスタイルを指定して、先ほどのSVG領域に追加。

円オブジェクトを追加することができました。
めでたしめでたし。

ちょっとまて。

さっきから「名前空間」という言葉が出てきているのだが、何なのだそれは。
〜となった方のために、次のsectionで説明します。

名前空間とは?


名前空間とは、ある限られた範囲において、名称とその対象となるものが定められたものです。
〜と言っても、ピンとこないかもしれません。

例をあげてみましょう。
サザエさんにおいての「お父さん」を指す人物。
磯野家では「お父さん」は「波平」ですが、フグ田家では「お父さん」は「マスオ」です。

磯野家とフグ田家が混在している中で、「お父さん」といっても一意の人物を参照することができません。そこで、それぞれの名前空間を用意してあげる必要があります。

名前空間とは⬆︎のようなものです。
「磯野家」「フグ田家」というそれぞれの範囲において、名前とその対象が定められています。

これらの名前空間の定義を指定した上で「お父さん」を参照すれば、

「磯野家の名前空間」における「お父さん」  ▶︎ 波平 「フグ田家の名前空間」における「お父さん」  ▶︎ マスオ

というように。
これで「波平か?マスオか?」と困惑することなく、一意の人物を特定することができますね。

HTMLやSVGなどのマークアップ言語においても、それぞれが内部に持つタグ名が混同したりしないよう、「名前空間」が定められています。

■ HTMLの名前空間名 「「1"http://www.w3.org/1999/xhtml" 」」 ■ SVGの名前空間名 「「5"http://www.w3.org/2000/svg" 」」

それぞれの名前空間には名称が付けられています。一見urlのようにも見えますが、慣例として「url風の名前」が付けられるようになっているだけで、これらの名称は単なる文字列です。

「HTMLとSVG」など、1つのコード内に複数の名前空間が混在するとき。
状況に応じてこれらの「名前空間名」を指定することで、タグ名の衝突などを回避することを可能にしている、というわけです。

なぜcreateElementじゃダメなのか?


ここで不思議に思うこと。

<div id = "area"> <svg width = "100%" height = "100%"> <circle cx = "50%" cy = "50%" r = "20%" fill = "yellow"/> </svg> </div>



HTMLコード内に<svg>要素を直接記述したときには、ブラウザはちゃんと認識して表示してくれます。これは現行のHTMLがSVGに準拠しているので、記述された<svg>タグに対して自動的にSVGの名前空間を適用してくれるためです。


document.createElement("svg")「「4 //◀︎ 無効」」

ではなぜ、名前空間を指定しないcreateElement( )のときにはブラウザは反応してくれないのでしょうか?
それにはこのcreateElementメソッドの働きが関係しています。

<body>内に直接<svg>タグを使ってコードを記述した場合。
先述のとおりブラウザは要素とその内部に対し、SVGの名前空間を付与してくれます。

一方で、createElement("svg")とした場合。

createElement( )メソッドは、引数に入っているタグ名を「HTMLの名前空間から探す」という性質を持っています。

ここで <p>や<img>など、HTMLの名前空間に該当するものが見つかれば、その要素を返しますが、該当するものが見つからない場合には「認知されていない要素」として扱われます。

「認知されていない要素」として扱われると、どうなるのでしょうか。例えば要素名を「unknown」として試してみます。

<div id = "area"> <unknown style = "width:5em;height:5em;background-color:blue;"> </unknown> </div>



widthとheight、そして背景色を明示しているのにもかかわらず、何も表示されません。

<svg>も認知しない。



そして。
SVGについても、同じ現象がおきます。現行のHTMLはSVGをサポートしてはいるものの、HTMLの名前空間に含まれているわけではありません
したがってHTML名前空間から探すcreateElement( )においては、「認知されていない要素」として扱われてしまうのです。

そのため、名前空間を引数に渡すことのできるcreateElementNS( )メソッドで名前空間を指定し、「この名前空間から探してね」とブラウザに依頼する必要があるのです。

まとめ。


これまで見てきたことをまとめます⬇︎。

■ 現行のHTMLはSVGの名前空間をサポートしている。
コード内に<svg>やその子要素を記述すると、SVG要素としてちゃんと認識される。

■ createElement( )メソッドは、引数に指定された要素名をHTMLの名前空間からしか、探してくれない。そのためSVGの要素名は「認知されていない要素名」として扱われてしまう。


〜以上のことから、<svg>やその子要素を動的に生成する場合、createElementNSを使って「名前空間」と「要素名」の両方を渡してやる必要がある。


<svg>をなぜフツーのcreateElement( )メソッドで生成することができないのか。その原因は、このメソッドの性質によってもたらされるものだったのです。
これで、納得した上でcreateElementNSを使うことができますね!

最後までお読みくださり、ありがとうございました。今回の内容、参考にしていただければ幸いです。

ではまた〜 ♩















「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。