以下の内容はhttps://shiroyuki2020.hatenablog.com/entry/introduction_to_svg_29より取得しました。


SVG|JavaScriptを含むSVGをHTMLに読み込ませる

SVGは、ブラウザで表示して使うことを想定しています。今までの勉強で静止画(ロゴなど)は、問題なく扱えるようになったと思います。ここからは一歩踏み込んで、JavaScriptを含むSVGをHTMLに読み込ませる方法を勉強しました。

実現したいこと

JavaScriptを含むSVGをHTMLに読み込ませたいです。

SVGの勉強をしていくうちに、このように考えると思います。HTMLには、以下のように最小限のコードで追加したいです。

<!-- sample.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SVGの練習</title>
</head>
<body>
...
<!-- SVGの読み込み -->
<object data="sample.svg" type="image/svg+xml"></object>
...
</body>
</html>

現状

現状、SVG+JavaScriptをブラウザで実現するには、HTMLに直書きするか、objectタグで読み込む方法の2択のようです。JavaScriptを含むSVGをobjectタグで読み込む場合、ブラウザの対応状況がまちまちなので、できる場合とできない場合があります。

ここからは、HTMLに直書きする方法とobjectタグで読み込む方法を例示します。

サンプルのデモ

以下は、円をクリックすると円の半径が大きくなるサンプルのデモです。

HTMLに直書きする方法

上記のサンプルをHTMLに直書きする場合は、以下のようになります。

<!-- sample.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SVGの練習</title>
</head>
<body>

<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">

<!--  定義 -->
<defs>
  <symbol id="c">
    <circle cx="100" cy="100" r="50" id="circle"/>
  </symbol>
</defs>

<!--  参照 -->
<use href="#c" fill="navy"/>

<!--  処理 -->
<script type="text/ecmascript">
const circle = document.getElementById('circle');
let size = circle.getAttribute("r")/1;
const r = 10;

circle.addEventListener('click', function(){
  size += r;
  if(size > 100){
    size = 50;
  }
  // console.log(size);
  circle.setAttribute("r", size);
});
</script>
</svg>

</body>
</html>

上記のようなコードは、可読性の観点からあまりよろしくありません。SVGJavaScript、(CSS)をHTMLから分割して、別ファイルとして読み込むのが理想的だと考えます。

objectタグで読み込む方法1

HTMLからSVGを分割して、別ファイルにします。そして、objectタグでSVGを読み込みます。

<!-- sample.svg -->
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">

<!--  定義 -->
<defs>
  <symbol id="c">
    <circle cx="100" cy="100" r="50" id="circle"/>
  </symbol>
</defs>

<!--  参照 -->
<use href="#c" fill="navy"/>

<!--  処理 -->
<script type="text/ecmascript">
const circle = document.getElementById('circle');
let size = circle.getAttribute("r")/1;
const r = 10;

circle.addEventListener('click', function(){
  size += r;
  if(size > 100){
    size = 50;
  }
  circle.setAttribute("r", size);
});
</script>
</svg>

SVGの中には、スタイルとJavaScriptが混在した状態です。

<!-- sample.html -->
<object data="sample.svg" type="image/svg+xml"></object>

objectタグで読み込む方法2

SVGからJavaScriptを分割して、別ファイルにします。

<!-- sample.svg -->
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">

<!--  定義 -->
<defs>
  <symbol id="c">
    <circle cx="100" cy="100" r="50" id="circle"/>
  </symbol>
</defs>

<!--  参照 -->
<use href="#c" fill="navy"/>
</svg>

JavaScriptを分割できましたが、スタイル(CSS)は残ったままです。

/* sample.js */
window.onload = function(){
  const svgFig = document.getElementById('svgFig').contentDocument;
  const circle = svgFig.getElementById('circle');
  let size = circle.getAttribute("r")/1;
  const r = 10;

  circle.addEventListener('click', function(){
    size += r;
    if(size > 100){
      size = 50;
    }
    circle.setAttribute("r", size);
  });
};
<!-- sample.html -->
<object id="svgFig" data="sample.svg" type="image/svg+xml"></object>
<script type="text/javascript" src="sample.js"></script>

分割したSVGファイルとJavaScriptファイルを読み込みます。

懸念点

SVGからスタイルを分割できていないのが残念です。

参考サイト




以上の内容はhttps://shiroyuki2020.hatenablog.com/entry/introduction_to_svg_29より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14