tags:

views:

391

answers:

2

Example:

<div id="big">&nbsp;</div>
<div class="small">&nbsp;</div>
<div class="small">&nbsp;</div>
<div class="small">&nbsp;</div>
<div class="small">&nbsp;</div>
<div class="small">&nbsp;</div>
<!-- ...and so on -->

"#big" is positioned absolutely behind a portion of the ".small"s, but is not a parent element.

I have been doing this:

           var smallArray = [];

           var $big = $('#big');
           var $bigPos = $big.offset();

           $('div.small').each(function() {
                    var $this = $(this);
                    var $thisPos = $this.offset();

                    if(
                            $thisPos.left >= $bigPos.left &&
                            $thisPos.left <= $bigPos.left+$big.outerWidth() &&
                            $thisPos.top >= $bigPos.top &&
                            $thisPos.top <= $bigPos.top+$big.outerHeight()
                    ) smallArray.push($this);
            });

...but this seems kludgy. Am I missing out on some methods of jQuery or vanilla JavaScript that will allow me to do this in a more elegant & efficient manner?

Thanks ahead for any help you can provide.

A: 
function aabbIntersect(sourceQuery, targetQuery) {
    var intersects = [];

    var $source = $(sourceQuery);
    var sAxis = $source.offset();
    var s_x = [sAxis.left, sAxis.left + $source.outerWidth()];
    var s_y = [sAxis.top, sAxis.top + $source.outerHeight()];

    $(targetQuery).each(function() {
              var $this = $(this);
              var thisPos = $this.offset();
              var t_x = [thisPos.left, thisPos.left + $this.outerWidth()]
              // if the x vector or y vector of the source are greater
              // than the target, they don't intersect, otherwise they do.
              // only compute the y vector if we have to.
              if ( ! (s_x > t_x 
                      || s_y > [thisPos.top, thisPos.top + $this.outerHeight()]) 
                 ) {
                  intersects.push($this);
              }
    });
    return intersects;
}

AABB means "axis aligned bounding box". There's a good tutorial on AABB detection in 2d I referenced to make sure I was not making a mistake. My code above assumes that just because an object covers the same pixel doesn't mean they're overlapping; feel free to adjust that.

mindlace
As this proves, your formula does not work: http://pastebin.me/213c55adc2efa54297a1d6c221357f79
cmcculloh
+1  A: 

This formula will detect if any of the specified elements is overlapping a target element:

function findIntersectors(targetSelector, intersectorsSelector) {
    var intersectors = [];

    var $target = $(targetSelector);
    var tAxis = $target.offset();
    var t_x = [tAxis.left, tAxis.left + $target.outerWidth()];
    var t_y = [tAxis.top, tAxis.top + $target.outerHeight()];

    $(intersectorsSelector).each(function() {
          var $this = $(this);
          var thisPos = $this.offset();
          var i_x = [thisPos.left, thisPos.left + $this.outerWidth()]
          var i_y = [thisPos.top, thisPos.top + $this.outerHeight()];

          if ( t_x[0] < i_x[1] && t_x[1] > i_x[0] &&
               t_y[0] < i_y[1] && t_y[1] > i_y[0]) {
              intersectors.push($this);
          }

    });
    return intersectors;
}

Here is a POC.

This SO question was very helpful in solving this problem.

cmcculloh
I also needed to detect overlapping elements in jQuery, and had been using the "jquery-overlaps" plugin, but it sometimes crashes IE. This function was a great replacement. Thanks!
shipshape