12

I wrote most of the code... And when the element is "fully" over the other element it works. The problem is that I don't just want it to be true when the element is "fully" over the element, I also want it to be true when the element is partly over the other element.

Here is my code:

    element = this.element.getStyles('left', 'top', 'width', 'height');
    elementLeftX = element.left.toInt();
    elementLeftY = element.top.toInt();
    elementRightX = (element.width.toInt() + element.left.toInt());
    elementRightY = (element.top.toInt() + element.height.toInt());

    el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el); // Element drop area
    elLeftX = el.left.toInt();
    elLeftY = el.top.toInt();
    elRightX = (el.width.toInt() + el.left.toInt());
    elRightY = (el.height.toInt() + el.top.toInt());

   if (((elLeftY <= elementLeftY) && (elementLeftY <= elRightY)) && ((elLeftY <= elementRightY) && (elementRightY <= elRightY))) {
        if (((elLeftX <= elementLeftX) && (elementLeftX <= elRightX)) && ((elLeftX <= elementRightX) && (elementRightX <= elRightX))) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }

I am very confused and I have been playing around for a while and I just can't get it to work.

jnbdz
  • 4,863
  • 9
  • 51
  • 93
  • 1
    Getting the style of an item will not give you its absolute position. If the item is wrapped in another element that has its own positioning, what then? More to consider here. – Diodeus - James MacFarlane Mar 07 '12 at 18:52
  • Yes, well it's not really a problem. I don't think it would be that hard to adjust. – jnbdz Mar 07 '12 at 18:57

3 Answers3

25

Standard video game method:

doElsCollide = function(el1, el2) {
    el1.offsetBottom = el1.offsetTop + el1.offsetHeight;
    el1.offsetRight = el1.offsetLeft + el1.offsetWidth;
    el2.offsetBottom = el2.offsetTop + el2.offsetHeight;
    el2.offsetRight = el2.offsetLeft + el2.offsetWidth;

    return !((el1.offsetBottom < el2.offsetTop) ||
             (el1.offsetTop > el2.offsetBottom) ||
             (el1.offsetRight < el2.offsetLeft) ||
             (el1.offsetLeft > el2.offsetRight))
};

See demo

mVChr
  • 49,587
  • 11
  • 107
  • 104
  • 3
    I noticed that this will also return true not only on overlap, but also if they are touching but not overlapping. If you want overlap only, change the `<`s and `>`s to `<=` and `>=`. http://jsfiddle.net/Emy49/1/ – mVChr Mar 08 '12 at 10:42
  • Please remember that both elements have to be visible in the DOM! So, for example, if you are `appendChild` new elements to the current DOM, make sure to do it before calling the above function. This information is particularly useful to the Google extension developers if you add new elements to already existing DOM. Also, in my case, I couldn't get `offset` values so I got them by calling `let el1Val = el1.getBoundingClientRect()` and then just replaced variables to, e.g. `el1Val.bottom <= el2.offsetTop`. – GoodOldGuy Feb 20 '21 at 18:10
  • Does not work with position absolute elements – Sylar Nov 19 '22 at 06:30
0

If you are interested in using jQuery (or if you already are) there are some great collision detection plugins available. Here is a previous answer detailing one https://stackoverflow.com/a/6052254/374866

Community
  • 1
  • 1
davehale23
  • 4,374
  • 2
  • 27
  • 40
0

When you are attempting is called "collision detection". You need to get the element's COMPUTED offsets and dimensions, not just the element's style declarations.

This posting may help explain:

jQuery/JavaScript collision detection

Community
  • 1
  • 1
Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176