2013-01-21 14 views
17

私はSVGキャンバスに追加しているすべての要素に対して共通のクリックハンドラを用意しようとしています。しかし、ハンドラを新しく作成した要素に委譲することはできません。 SVG要素のイベント委譲

この

は私が委任しようとしたコードが、運です

$("#floor").on('click','.drawnLine', function() { 
    //#floor is the SVG Element 
    //.drawnLine is the <line> element that is added dynamically 
    console.log($(this).data('index')); 
}); 

更新:委任:

注意がいることを言及している.on()のjQueryのマニュアルで イベントはSVGでは機能しません。

ここで問題は、この問題の他の回避策ですか?

+0

jQueryはHTML DOM用に設計されていますが、これはSVG DOMと似ていますが同一ではありません。おそらくあなたがしようとしていることはサポートされていません。 (同様に、以前のプロジェクトで独自のSVG互換バージョンでクラスを追加/削除するためのいくつかのjQueryメソッドを置き換える必要がありました)うまくいけば、誰かが良い代替案を提案できることを願っています。 –

+0

[http://keith-wood.name/svg.html](http://keith-wood.name/svg.html) – Ohgodwhy

+0

@Ohgodwhy、イベント委任はそのライブラリでも動作しません。 – Starx

答えて

12

jQueryがSVGで失敗すると、vanilla jsを使用できます。幸いにも、svgをサポートするすべてのブラウザもイベントリスナーをサポートしています。

$("#floor")[0].addEventListener('click', function(e) { 
    // do nothing if the target does not have the class drawnLine 
    if (!e.target.classList.contains("drawnLine")) return; 
    console.log($(this).data('index')); 
}); 

しかし、あなたのイベントをよりきれいに委譲する独自の機能を作成することもできます。

+1

最近の別のオプションは 'e.target.classList.contains(" drawnLine ")'です。何か新しい。 –

+1

イベントハンドラをアタッチする要素と要素の間の祖先に 'pointer-events:none'を設定し、' pointer-events:auto'をオンにすることで、イベントターゲットにする子要素を分離することができますターゲット要素。例えば。あなたの '.drawnLine'要素が' 'の中の' 'の中にあるなら' 'と' 'と' auto'に 'pointer-events'を' none'に設定してください。 '.drawnLine'要素に追加します。 – ericsoco

8

TL/DR:イベントリスナーをSVG以外の親要素にアタッチします。

jQueryドキュメントの注釈はやや誤解を招きます。

委任されたイベントはSVGでは機能しません。

リスナーが SVGに装着されたときにそれはおそらく...

委任イベントはを動作しませんする必要があります。

jQueryのイベント委任は、イベントリスナーがSVG要素にアタッチされていると機能しません。ただし、リスナーをSVGの非SVG親にアタッチすると、イベントの伝播が期待どおりに機能し、SVG要素に一致するセレクタが実際にイベントハンドラ関数をトリガします。

$("#floor").on('click','.drawnLine', function() { 
    console.log($(this).data('index')); 
}); 

しかし、親要素に取り付けるには動作します:

$(document.body).on('click','#floor .drawnLine', function() { 
    console.log($(this).data('index')); 
}); 

注:私は1つの癖きた仕事をませんSVG要素にリスナーをアタッチ

イベントターゲットがSVG要素の場合、イベントはiOS上のdocument.bodyまでバブルアップしないことに注意してください。したがって、iOSユーザがハンドラ関数をトリガできるようにするには、イベントリスナを間にあるいくつかの要素(SVGが存在するdiv要素など)に接続する必要があります。

+0

ありがとうございます。これは非常に役に立つ応答です。あまりにも多くのイベントハンドラを必要とせずに、ターゲット要素に関連付けられたd3データに簡単にアクセスできるようになりました。 – hrabinowitz

関連する問題