web-dev-qa-db-ja.com

JavaScriptに埋め込まれたSVGの要素にクリックイベントを追加する

私は WikipediaからのこのSVG画像 を取得し、次のコードを使用してWebサイトに埋め込みました。

<embed src="circle1.svg" type="image/svg+xml"/>

これを実行すると、要素を検査してソ​​ースコードを確認できます。画像内のすべての国は個別の要素です。国をクリックすると、その国のIDが通知されます。SVGにはすべての国に2文字のIDがあるからです。誰かがこれを行う方法を知っていますか?要素に配置した方が簡単でしょうか?

16
Daan Lambrechts

私の問題に対する答えを見つけたあなたのコメントを使って大丈夫です。このコードをsvg自体に追加しました。

<script type="text/javascript"> <![CDATA[
    function addClickEvents() {
        var countries = document.getElementById('svg1926').childNodes;
        var i;
        for (i=0;i<countries.length;i++){
            countries[i].addEventListener('click', showCountry);
        }
    }

    function showCountry(e) {
        var node = e.target;
        if (node.id != 'ocean') {
            node = getCorrectNode(node);
        }
        alert(node.id);
    }

    function getCorrectNode(node) {
        if (node.id.length == 2 || node.id == 'lakes') {
            return node;
        }
        return getCorrectNode(node.parentNode);
    }
]]> </script>

関数addClickEventsは、svgのロード時にトリガーされます。しかし、私はまだこれに別の問題を抱えています。このsvgを(コードと共に)HTMLドキュメントに埋め込む必要があります。

<embed src="circle1.svg" type="image/svg+xml" />

IDを警告する代わりに、HTMLドキュメントのdivに配置する必要があります。 svgからこのIDを取得するにはどうすればよいですか?

4
Daan Lambrechts

これが example です。これは、実行しようとしていることに非常によく似ています。 <embed>の代わりに<object>を使用していますが、それはほんの小さな詳細です。親ドキュメントから埋め込みドキュメントのDOMにアクセスする方法については、この他の を参照してください。DOMは2つのドキュメント間でわずかに異なります。

また、ウィキペディアにあるsvgマップは非常に大きいため、実際のWebサイトで実際に使用する前にsvgを最適化することをお勧めします。例: SVG Cleaner または SVG Scour

16
Erik Dahlström

SVGがDOMに含まれている場合は、基本的なHTMLと同じ方法で、イベントリスナーを個別の要素にアタッチできます。 jQueryを使用する1つの例は次のようになります: http://jsfiddle.net/EzfwV/

更新:ほとんどの最近のブラウザーはインラインsvgをサポートしているため、ソースをDOMにロードするには、リソースからそれをロードするだけです(jQueryのload()などを使用)。

編集:より具体的な例 http://jsfiddle.net/EzfwV/3/

7
Jlange

2016年7月の更新

同じドメインから何かを埋め込むという条件の下で、embed要素からのイベントに応答することができます。これの簡単なデモンストレーションをJSFiddleとして作成しました。最も重要な部分は、embeddingElement.contentDocumentを介して埋め込みドキュメントにアクセスできることです。そこから、SVG要素にアクセスし、クリックイベントハンドラーをインストールできます。

実装メモ:デモでは、すべてのpath要素にイベントハンドラーを追加します。パフォーマンス上の理由から、おそらく単一のイベントハンドラーをSVGに追加してから、ハンドラーでイベントターゲットを使用します。編集:このように更新されたフィドル

古い答え

Googleをすばやく検索すると here が表示されました。それがあなたの問題の答えだと思いますよね?

ここでまとめると、embed要素のイベントをキャプチャすることはできません。残念ながら、唯一の解決策はSVGファイルを変更することです。

JavaScriptをSVGファイルに埋め込む方法の小さな例を次に示します(JSFiddle)。これは、IBM developerWorksの example に基づいています。

<svg>
  <script type="text/javascript">
    <![CDATA[
    var redVal = 0;
    var greenVal = 0;
    var blueVal = 0;

    function changeCol(evt) {
       redVal = Math.round(Math.random() * 255);
       greenVal = Math.round(Math.random() * 255);
       blueVal = Math.round(Math.random() * 255);
       evt.target.setAttribute("fill",
             "rgb(" + redVal + "," + greenVal + "," + blueVal + ")");

    }
    // ]]>
  </script>
  <circle cx="200" cy="200" r="100" fill="blue"
          onclick="changeCol(evt)" />
</svg>
4
Just a student

簡単な方法は

  • JavaScriptを使用してSVGで動的にパスを作成する
  • スタイルを動的に追加する
  • パスへのイベントの追加
  • 既存のSVGに追加します。

スクリプト

 <svg id="mySvg"></svg>

var XMAX = 500;
var YMAX = 500;
var _xx=10;
var _reg=100;
var _l=10;
// Create PATH element
for(var x=1;x<20;x++)
{
var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
pathEl.setAttribute('d','M'+_l+' 100 Q 100  300 '+_l+' 500' );
pathEl.style.stroke = 'rgb('+(_reg)+',0,0)';
pathEl.style.strokeWidth = '5';
pathEl.style.fill = 'none';
    $(pathEl).mousemove(function(evt){$(this).css({"strokeWidth":"3","stroke":"#ff7200"}).hide(100).show(500).css({"stroke":"#51c000"})});

$('#mySvg').append(pathEl);
_l+=50;
}

JSFiddleのライブデモ

1
Godly Mathew