8

この画像のように、部分的に重なっている SVG 要素で mousemove イベントを検出しようとしています。

ここに画像の説明を入力

フィドル

<svg>
    <rect id="red"    x=10 y=10 width=60 height=60 style="fill:#ff0000" />
    <rect id="orange" x=80 y=10 width=60 height=60 style="fill:#ffcc00" />
    <rect id="blue"   x=50 y=30 width=60 height=60 style="fill:#0000ff; fill-opacity: 0.8" />
</svg>

$('rect').on('mousemove', function()
{
    log(this.id);
});

ここで、青と赤の交差点にマウスを合わせると、これらの要素の両方でマウス イベントを検出したいと思います。青とオレンジの組み合わせについても同様です。ログでわかるように、そのような場合、イベントは現在、一番上にある青いボックスに対してのみ発生します。

青の要素の pointer-events を none に設定することで、青の要素をホバリングしている間に赤とオレンジの要素がイベントを発生させることができるため、これはポインターイベントに関係しています。しかし、その後、青いボックスのイベントを取得できないため、これも実行可能なオプションではありません。

この問題を解決するライブラリを使用します。この d3 exampleのようにイベント バブリングを見ましたが、それは DOM にネストされた要素に対してのみ機能します。他の多くの要素と重複する可能性のある独立した要素がたくさんあるため、DOM をそのように構成することはできません。

最後の手段は、現在のマウス位置にある要素を見つけて、手動でイベントを発生させることだと思います。したがって、document.elementFromPoint()を見ましたが、それは 1 つの要素しか生成しません (SVG では機能しない可能性があります?)。指定された位置にある要素を検索するjQuerypp関数が 内に見つかりました。ここを参照してください。この例は、SVG 内ではなく DIV であることを除いて、見栄えがします。div を svg の四角形要素に置き換えると、フィドルが壊れたように見えます。

私は何をしますか?!

4

2 に答える 2

7

ここでの素晴らしいコメントが答えをくれました:カーソル位置でgetIntersectionList()を使用してそれらを見つけることにより、イベントを基になる要素に手動で伝播することが可能です。

$('svg').on('mousemove', function(evt)
{
    var root = $('svg')[0];
    var rpos = root.createSVGRect();
    rpos.x = evt.clientX;
    rpos.y = evt.clientY;
    rpos.width = rpos.height = 1;
    var list = root.getIntersectionList(rpos, null);

    for(var i = 0; i < list.length; i++)
    {
        if(list[i] != evt.target)
        {
            $(list[i]).mousemove();
        }
    }
});

作業例: http://jsfiddle.net/michaschwab/w0wufbtn/6/

他のリスナーが元のイベント オブジェクトを必要とする場合は、http://jsfiddle.net/michaschwab/w0wufbtn/13/を確認してください。

どうもありがとう!!

于 2015-04-01T19:14:26.767 に答える