〽️3つ目の読み込み方。 〽️SVGにJavaScriptを埋め込む。 〽️object要素としてSVGを呼び出す。 〽️idなどの衝突もなし。 〽️object要素、最強?
⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。
<script><![CDATA[ bb「「3 〜 内容 〜」」 ]]></script>
<object data = 「「5"〇〇.svg"」」> </object>
こんにちは、「ふ」です。
HTMLにSVGを読み込む方法として代表的なのが、<img>タグで呼び出す「参照表記」と、直接<svg>要素としてデータをHTMLに記述する「インライン表記」です。
当コーナーでもこの2つの方法をベースに色々な記事を展開してきました。しかし、それぞれにメリット/デメリットもあります。
■ 参照表記
・コードも短くて、とにかくお手軽
・SVG内の要素にアクセスできない
・SVGコード内に埋め込んだimageやJavaScriptが反映されない
■ インライン表記
・通常のHTML要素のように、子要素にアクセスしてScriptでも何でもあり
・HTMLのコードが長くなってしまう
・複数のSVGを取り込んだ場合、classやidの衝突に配慮する必要あり
特に選択に困るのが、JavaScriptを実装したSVG画像を、1つのページに何個も読み込むときです。例えば、記事一覧のサムネイルの部分などがそれにあたります。
参照表記ではScriptが動かないし、かといって全てインライン表記にすると、莫大なコード量となり、要素同志のidやclass名の衝突も心配。
HTMLにSVGを読み込む3つ目の方法、それが<object>タグによる呼び出しです。
SVGを<object>タグで呼び出した場合、内部のJavaScriptはweb上でもちゃんと動きます。また、HTMLでの呼び出しも参照表記のようにタグ1発でOKで、外部ファイルにつきidやclass名の汚染もありません。
今回はSVG内にJavaScriptを埋め込んで、HTML上の<object>タグで呼び出す手順について紹介していきます。
SVGファイル内にJavaScriptのコードを埋め込む際には、CDATAセクションを使用する必要があります。
SVGファイルは、xml形式のマークアップ言語で記述されています。
JavaScriptでは演算子などの意味を表す目的で、「<」 「>」が時折使用されます。
しかしそのまま「<」「 >」をSVGコード内に記述すると、ファイルが読み込まれたときに何らかのタグだと誤認されてしまいます。
また「&」も、そのあとに続くテキストによっては文字実体参照の表現となってしまうので、そのまま記述するのはよろしくありません。
そこでSVGファイル内にJavaScriptを埋め込むときには、CDATAセクションというものを利用します。
<script> bb「「1<![CDATA[」」 bb「「3 〜 コード 〜」」 「「1bb]]>」」 </script>
使い方としては、<script>タグの内側に <![CDATA[ 〜 ]]>を挿入し、その中にJavaScriptのコードを記述します。
この<![CDATA[ 〜 ]]>の内側に書かれた「<」「>」「&」はマークアップの部品ではなく、単なる「テキスト」として認識されます。
■ sample.svg
実際にやってみましょう。
サンプルとして⬆︎のSVG画像「sample.svg」を用意しました。
円オブジェクトに対して、マウスオーバー/マウスアウトで色が変わる、というイベントリスナを実装します。
<svg viewBox="0 0 841.9 595.3"> <style type="text/css"> .st0{fill:#00A0E9;stroke:#231815;stroke-miterlimit:10;} .st1{fill:#E4007F;stroke:#231815;stroke-miterlimit:10;} </style> <circle id = 「「5"maru"」」 class="st0" cx="269.6" cy="297.6" r="103.2"/> <rect x="469.1" y="194.4" class="st1" width="206.5" height="206.5"/> <script> 「「1<![CDATA[」」 const maru = document.getElementById(「「5"maru"」」); maru.addEventListener("mouseover",() => maru.style.fill = "yellow"); maru.addEventListener("mouseout",() => maru.style.fill = "#00A0E9"); 「「1]]>」」 </script> </svg>
円オブジェクトにid名「maru」を付けて、JavaScript側で呼び出しています。
もともとの塗りはシアンですが、マウスカーソルが乗るとイエローに、離れるとシアンに戻るようにしました。
〜これでSVGファイル側の準備はOKです。
それではHTML側で<object>タグを使って、先ほどのSVG画像を呼び出してみましょう。
で、
<object>は、HTMLファイルにさまざまな外部ソースを読み込むことのできる便利な要素です。
<img>要素のように「単なる画像」として読み込むのではなく、JavaScriptなどの実装データもいっしょに読み込み→web上で反映してくれます。
object要素で読み込めるデータには画像、音声、外部HTMLファイルなどがありますが、SVGもその対象に含まれています。
記述は<img>タグのように、とてもシンプルです。
data属性にファイルのurlを指定するだけです。
<object data = 「「5"〇〇.svg"」」> </object>
sample.svgが表示されました。
マウスカーソルをのせて(タッチデバイスの場合はタップして)みてください。埋め込んだJavaScriptもちゃんと動作しています。
もちろんCSSを使って、画像の位置やサイズその他を指定することができます。
<object>要素を使うもう1つのメリット。
HTML上で複数のSVG画像を呼び出した場合、ファイルの内容が干渉し合うことがありません。実験してみます。
「sample.svg」を複製し、「sample2.svg」とします。
そしてマウスオーバー時の色だけを「グリーン」に変えて、その他は一切変更しません。
■ sample2.svg
<svg viewBox="0 0 841.9 595.3"> 「「3 <!--他は変更なし-->」」 maru.addEventListener("mouseover",() => 「「1maru.style.fill = "green"」」); 「「3 <!--他は変更なし-->」」 </svg>
現状、2つのファイル間ではid名や宣言した定数名は同じものです。
2つのSVGを並べて表示してみましょう。
<object data = "sample.svg"> <object data = "sample2.svg">
■ sample.svg
■ sample2.svg
結果です。
sample.svgでは円にカーソルを乗せると(タップすると)イエローに変わります。
sample2.svgではグリーンに変化します。
双方のファイルにおいて、id名「maru」や定数「maru」が被っているのですが、それぞれで実装された内容に従って動作しています。
もし、2つのSVGデータをインラインで直接HTMLに記述した場合、オブジェクトのid名やJavaScript内で宣言している定数名を別のものに書き換えないと、うまく動作しません。
SVGファイルを<object>要素として呼び出した場合、完全に別のリソースとして読み込ませることが可能です。内容の重複に配慮する必要がありません。
最後までお読みくださり、ありがとうございます。
<object>要素を使ったSVG呼び出し。
外部SVG読み込みの方法としては、今のところ弱点は見当たらず。最強なのかもしれません。
冒頭で述べたような「複数のSVGを貼り付ける」ケースでは、コードも簡潔になり、すごく便利です。
「SVGファイル内で実装が完結していて、あとは表示するだけ」の場合には、積極的に使っていきましょう。
ではまた〜 ♪
JavaScriptの矢印「=>」〜これはアロー関数というものです。
2022.01.09
使い方とメリットについて解説。
SVGでWeb Animations API。
2020.11.12
〽️ ネイティブJavaScriptでのアニメーション。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。