2012年9月26日水曜日

svgのuse要素を使ってハイパーリンクをコピーする

実用度がどれほど有るのか分からないけれど,use要素を使えばハイパーリンク情報をコピーすることができるようだ.上手く使えばhtml文書内のリンク情報のみを別ファイルにまとめると言った用途に応用できそうだが,やはりブラウザ間で動作が違うのであった.

svgのuse要素は他の任意の要素を複写することで,複雑な図形定義を流用可能とする機能をもちます.その際に,ハイパーリンクが挿入されている図形をuse要素から参照すると,ハイパーリンクごと図形が複写されることが判りました.

それでは実際に試してみましょう.


<!--ハイパーリンクを定義するsvg-->
<svg display="none">
 <defs>
  <g id="link_a">
            <a xlink:href="https://www.google.co.jp" target="_blank">
    <rect x="0" y="0" width="100" height="100" fill="blue"/>
   </a>
  </g>
 </defs>
</svg>

<!--ハイパーリンクを使う側のsvg-->
<svg width="300px" height="300px" viewBox="0 0 300 300">
 <use xlink:href="#link_a" x="0"/>
    <use xlink:href="#link_a" x="150"/>
</svg>

やり方は非常にシンプルです.
  • 図形要素にa要素でハイパーリンクを設定し,それをg要素で囲みます.
  • このg要素をuse要素から参照します.
    a要素はuse要素から参照することが出来ません.
これだけで同一のリンク先を持つ図形をいくらでも作り出すことが可能となります.ここではハイパーリンクがインラインsvg要素で定義されていますが,もちろん外部svgファイルに定義しておくこともできます(その場合はxlink:href属性に「[ファイル名].svg#[id]」を指定します).

従って複数ページにわたって同一のハイパーリンクを設定したボタン等を配置する必要がある場合は,このテクニックを用いることでハイパーリンク情報のみを外部に切り出すことができるため,メンテナンスが容易となるでしょう.


ですが,1点だけ注意すべき点があります.この例ではリンク先がフルパスで設定されているのですが,そうではない場合,例えば相対パスで指定する場合やページ内の要素へのハッシュ値(#id)を指定した場合,ブラウザにより動作が異なるのです.
  • firefoxの場合…use要素が参照しているsvg文書を基準にリンクが形成される.
  • chrome,operaの場合…use要素が存在する文書を基準にリンクが形成される.
  • 追記)ハッシュ値の場合,operaでは一度しかリンクが効かないと言った問題が発生する.
つまり,a.htmがuse要素を使ってa.svgのハイパーリンク「#a」をコピーしたとすると,firefoxでは「a.svg#a」へのリンクとして解釈され,chromeとoperaでは「a.htm#a」へのリンクとして解釈されるのです.些細な違いですが,ガラリと動作が異なってしまうので注意が必要です.

またここでもブラウザの差異が見つかりました.use要素は様々な可能性を秘めている要素なだけに,勿体ないことです.

追記)冷静に考えてみるとこれってhtmlでもobject(iframe)要素を使えば実現できるんじゃないか?
わざわざsvgを使わずともいい気がしてきたぞ.

0 件のコメント:

コメントを投稿