2012-03-28 5 views
5

「の後ろに」視覚的である要素にマウスイベントをディスパッチAとB:次のようにが、私は2つのdiv要素を持っている私のWebページで受光素子

enter image description here

DOMは(簡体字)になります。ここで注意すべき重要なことは、divがDOM階層内の同じレベルにあり、divで順序付けられていないことです。また、外側のDIVのみAおよびBだけでなく、複数のdivのC、D、E等Bを含んでいない必ずしもまたA.背後に横たわる、CかもしれA.によって重複されなくてもよい

<div> 
    <div style="...">B</div> 
    <div style="...">A</div> 
</div> 

Aクリックハンドラが外側のdivにアタッチされ、バブルフェーズでAまたはBのマウスクリックイベントがキャプチャされます。 AとBの交差点をクリックすると、A上のクリックイベントが発生し、クリックハンドラが今すぐ起動されます。

問題:特定の条件下では、ハンドラはイベントをAで処理すべきではなく、Bに属している必要があると判断します。Bで処理する必要があるイベントは、同じクリックハンドラを起動しますが、 currentTargetプロパティは、どのように私はこれを達成することができますBの代わりA.

されるのですか?

私はすでにCSS3ポインタ・ハンドラとJSのメソッドをディスパッチいくつかのイベントを見てきましたが、本当にここに解決策を考え出すことができませんでした。

解決策1(ないクロスブラウザ互換の)?

私は私がpointer-events css3 propertyを使用することが可能かもしれないと思います。ハンドラがイベントをBで処理する必要があると判断した場合、ポインタイベントをnoneに設定します。次に、マウスクリックを再トリガします。 質問ここではそれが唯一の座標が、特定の要素を指定しないとマウスクリックを再トリガすることは可能ですか?とにかく

、ポインタ・イベントのサポートが限られている:http://caniuse.com/pointer-events

+0

あなたが見てきましたHTTPS ://developer.mozilla.org/ja/CSS/poin ter-events – j08691

+0

はい、主な問題は、AまたはBのイベントを持つかどうかを動的に決定する必要があることです。 – Erik

+0

はjQueryのオプションですか?すでに – Yoshi

答えて

3

あなたは(jQueryのを使用して)Bにイベントを渡すことを試みることができます:

擬似コード

var $A = $('#A'), $B = $('#B'); 

$B.on('click', function() { 
    console.log('B clicked'); 
}); 

$('#outer').on('click', function (evt) { 
    if (Math.random() < 0.1) { // << pseudo condition 
     $B.trigger(evt); 
    } 
});​ 

http://jsfiddle.net/hzErh/


更新:このような関数を使用して

// this function should (did not enough testing) return all elements at a given 
// point in the order of top to bottom. 
var elementsFromPoint = function (x, y, root) { 
    var buffer = [], result = [], el, i = 0, lim; 

    while ((el = document.elementFromPoint(x, y)) && [root, document.body, document.body.parentNode].indexOf(el) < 0) { 
    result.push(el); 
    buffer.push({el: el, visibility: el.style.visibility}); 
    el.style.visibility = 'hidden'; 
    } 

    for (lim = buffer.length; i < lim; i += 1) { 
    buffer[i].el.style.visibility = buffer[i].visibility; 
    } 

    return result; 
}; 

あなたが与えられたX/Y座標のための要素を取得することができます。それは少しハッキーだし、より多くのテストが必要です。

$('#outer').on('click', function (evt) { 
    var elements = elementsFromPoint(
    evt.pageX + $(this).offset().left, 
    evt.pageY + $(this).offset().top, 
    this 
); 

    console.log(elements); 
}); 

デモ:http://jsfiddle.net/hzErh/1/


アップデート2:このバージョンは、多くの要素のためのより良い性能を与える必要があります。

// this function should (did not enough testing) return all elements at a given 
// point, though the order is not representative for the visible order. 
var elementsFromPoint = function (root, x, y) { 
    var result = [], i = 0, lim = root.childNodes.length, bb; 

    for (; i < lim; i += 1) { 
    bb = root.childNodes[i].getBoundingClientRect(); 
    if (bb.left <= x && x <= bb.right && bb.top <= y && y <= bb.bottom) { 
     result.push(root.childNodes[i]); 
    } 
    } 

    return result; 
}; 

デモ:http://jsfiddle.net/CTdZp/2/

+1

なぜMath.random()を使用しますか – Erik

+0

@Erik私はちょうどあなたの* "特定の条件" *;)をシミュレートしたかった – Yoshi

+0

ああ、そうです!それは良い解決策です。残念ながら、私は私の問題を説明するのに十分正確ではありませんでした。私の外側のdivには、aやbのようなdivボックスがたくさんあることがあります。メインの問題がここにくるので、どのボックスがクリックされたのかを知るにはどうすればいいですか? – Erik

関連する問題