2017-01-13 18 views
0

普通のJavascriptイベントハンドラをSVGタグ内の要素に付けることは可能です。私は非常に多くのオブジェクトのインスタンスを複製しようとしていますので、少し簡素化するために<def><use>タグを使用する予定です。しかし、私の子供のアイテムのそれぞれは、 "クリック"と他のイベントを処理する必要があります。私はそれぞれの子供のためにそれらのイベントを定義することができますが、私は何とか最初の項目でそれらを定義することができれば良いですし、ちょうどその "再利用"クリックイベント。これは可能ですか? 子要素の代わりにSVG <def>要素にJavascriptイベントを追加しますか?

https://jsfiddle.net/khyp1o0w/

<svg width="400" height="400" viewBox="0 0 400 400"> 
    <defs> 
     <rect id="someDef" x="0" y="0" width="60" height="30" fill="#f00" /> 
     <!-- ^^ would like to define an event here... --> 
    </defs> 

    <use x="150" y="150" xlink:href="#someDef" /> 
    <use x="250" y="250" xlink:href="#someDef" /> 
    <!-- ^^ ... that is used by these guys --> 

</svg> 

EDIT:例SVGを追加します。

+0

これは、[イベント委任](http://stackoverflow.com/q/1687296/2813224)という名前ですが、登録する代わりに子供のイベント、あなたは親に登録します。 – zer00ne

+0

@ zer00ne:私はイベントの委任を知っています。私はタグのSVG要素でこれを使用しようとしており、それを参照するタグに適用しています。 タグは、それらが参照するタグの本当の子ではないので、通常のイベント委任はここでは適用されないようです。 – loneboat

+0

私はあなたが何を持っているかわからないので、[mcve]を提供して、おそらくイベントの委任が可能かどうかを見ることができます。 – zer00ne

答えて

1

use要素の対象となるIIRC要素は、<use>がiframeの場合と同様に、<use>要素に内部的にコピーして内容を複製する必要があります。

これは、このイベントは、ノードのマークアップ(インライン)の一部である場合を除き、元のノードに取り付けられたイベントがコピー、にコピーされないことを意味します。しかし、クロムだからここに...本当にここスペックに従わないとさえ、それが動作することはありませんが、FFの例です:

// this won't work 
 
document.getElementById('someDef').addEventListener('click', function() { 
 
    this.setAttribute('stroke', randomColor()); 
 
});
<svg width="400" height="400" viewBox="0 0 400 400"> 
 
    <defs> 
 
    <script type="application/javascript"> 
 
     function randomColor() { 
 
     var letters = 'ABCDEF'.split(''); 
 
     var color = '#'; 
 
     for (var i = 0; i < 6; i++) { 
 
      color += letters[~~(Math.random() * 15)]; 
 
     } 
 
     return color; 
 
     } 
 
    </script> 
 
    <!-- this will work in FF --> 
 
    <rect id="someDef" onclick="this.setAttribute('fill',randomColor())" x="0" y="0" width="60" height="30" fill="#f00" /> 
 
    </defs> 
 

 
    <use x="150" y="150" xlink:href="#someDef" /> 
 
    <use x="250" y="250" xlink:href="#someDef" /> 
 
</svg>

あなたは可能性があり、コース使用イベントの代表団のリスニングによって、

var svg = document.querySelector('svg'); 
 
svg.addEventListener('click', function(e) { 
 
    var usedTargetID = e.target.getAttributeNS("http://www.w3.org/1999/xlink", 'href'); 
 
    switch (usedTargetID) { 
 
    case '#direct': 
 
     clickDirect(e); 
 
     break; 
 
    case '#nested': 
 
     clickNested(e); 
 
     break; 
 
    default: 
 
     return; 
 
    } 
 
}); 
 

 
function clickDirect(e) { 
 
    // what you seem to want 
 
    e.target.setAttribute('fill', randomColor()); 
 
} 
 

 
function clickNested(e) { 
 
    // will set both nested... 
 
    e.target.setAttribute('fill', randomColor()); 
 
} 
 

 
function randomColor() { 
 
    var letters = 'ABCDEF'.split(''); 
 
    var color = '#'; 
 
    for (var i = 0; i < 6; i++) { 
 
    color += letters[~~(Math.random() * 15)]; 
 
    } 
 
    return color; 
 
}
<svg width="400" height="400" viewBox="0 0 400 400"> 
 
    <defs> 
 
    <rect id="direct" x="0" y="0" width="60" height="30" /> 
 
    <g id="nested"> 
 
     <!-- you can only access this --> 
 
     <!-- not its content individually --> 
 
     <rect x="80" y="0" width="60" height="30" /> 
 
     <rect x="20" y="70" width="60" height="30" /> 
 
    </g> 
 

 
    </defs> 
 

 
    <use x="150" y="50" xlink:href="#direct" /> 
 
    <use x="250" y="150" xlink:href="#nested" /> 
 
</svg>
をそれとも、共同:あなたのルートSVG要素のクリックイベントのために、これはない、ネストされたもののために、唯一の直接ターゲット要素のために働くだろうuldは要素ごとにイベントを追加しますが、委譲と同じ制限があります。

関連する問題