8

基本的に画面を左から右にスキャンし、同じx座標を共有するすべての要素(重複する要素を含む)を調べるPURE Javascript(他のフレームワークはありません)を使用して、ラインスイープアルゴリズムを実装しようとしています。

例えば

画面上にランダムに境界線レイアウトの6divがあり、垂直線(青い点線)を使用して左から右にスキャンしています。

黒の境界線を持つ6つdivの要素があり、それらはすべて画面上にランダムにレイアウトされています。説明のために、垂直の青い点線を使用して、平面を左から右にスキャンします。目標は、行が通過したすべての要素を報告することです。上記の例では、JavaScriptを使用して、、、および内部をどのように報告しDiv Aますか?Div EDiv Dhyperlink DDiv D

4

2 に答える 2

3

getBoundingClientRectメソッドで要素の位置を取得できます。次に、それらをループして、スキャンと一致するかどうかを確認します。

var all = document.body.getElementsByTagName("*");
var x = /* blue line */;
var match = [];
for (var i=0; i<all.length; i++) {
    var rect = all[i].getBoundingClientRect();
    if (rect.left < x && rect.right > x)
        match.push(all[i]);
});

より短く機能的な方法:

var match = Array.prototype.filter.call(document.body.querySelectorAll("*"), function(el) {
    var rect = el.getBoundingClientRect();
    return rect.left < x && rect.right > x;
});

頻繁に使用するクイック アクセス機能が必要な場合は、すべての要素を (その座標と共に) ソートされたデータ構造であるセグメント ツリーに格納し、そこでそれらを検索できます。

また、DOM 要素の子ノードが親の境界を超えないことが保証されている場合は、DOM 自体を検索ツリーとして簡単に使用できます。

var x = /* the blue line */;
var match = function find(el, set) {
    var rect = el.getBoundingClientRect();
    if (rect.left < x && rect.right > x) {
        set.push(el);
        for (var i=0; i<el.children.length; i++)
            find(el.children[i]);
    }
    return set;
}(document.body, []);
于 2012-08-27T17:52:27.870 に答える
1
  1. すべての DOM 要素を集める
  2. それらの位置を見つけて、それらを配列に隠します (DOM を経由せずにデータを再度使用できるようにします)
  3. 配列をループして x を解く
于 2012-08-27T17:43:30.173 に答える