〽️ NSとは名前空間のこと。 〽️ 名前空間とは? 〽️ なぜcreateElementはダメなのか?
⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。
let svg1 = document.「「1createElementNS」」("http://www.w3.org/2000/svg","svg");
こんにちは、「ふ」です。
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サイト制作に役立ててください。
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つのコード内に複数の名前空間が混在するとき。
状況に応じてこれらの「名前空間名」を指定することで、タグ名の衝突などを回避することを可能にしている、というわけです。
ここで不思議に思うこと。
<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についても、同じ現象がおきます。現行のHTMLはSVGをサポートしてはいるものの、HTMLの名前空間に含まれているわけではありません。
したがってHTML名前空間から探すcreateElement( )においては、「認知されていない要素」として扱われてしまうのです。
そのため、名前空間を引数に渡すことのできるcreateElementNS( )メソッドで名前空間を指定し、「この名前空間から探してね」とブラウザに依頼する必要があるのです。
これまで見てきたことをまとめます⬇︎。
■ 現行のHTMLはSVGの名前空間をサポートしている。
コード内に<svg>やその子要素を記述すると、SVG要素としてちゃんと認識される。
■ createElement( )メソッドは、引数に指定された要素名をHTMLの名前空間からしか、探してくれない。そのためSVGの要素名は「認知されていない要素名」として扱われてしまう。
〜以上のことから、<svg>やその子要素を動的に生成する場合、createElementNSを使って「名前空間」と「要素名」の両方を渡してやる必要がある。
<svg>をなぜフツーのcreateElement( )メソッドで生成することができないのか。その原因は、このメソッドの性質によってもたらされるものだったのです。
これで、納得した上でcreateElementNSを使うことができますね!
最後までお読みくださり、ありがとうございました。今回の内容、参考にしていただければ幸いです。
ではまた〜 ♩
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。