Jordan Foreman
Jordan Foreman

Reputation: 3888

javascript - elementFromPoint select bottom element

I'm working on this drag and drop application with jquery/javascript, and I'm having to use a balance of the two to accomplish what I want.

var drop = document.elementFromPoint($(this).offset().left, $(this).offset().top);

what I'm trying to do with this code here is to get the element that my draggable is trying to be dropped in (is currently hovering over). This, however, will always return my draggable, as opposed to the the table cell (td) underneath it.

Since I know I am looking for a td element, is there a way to set var drop to be something like:

var drop = document.elementFromPoint(x, y, 'td')?

Or is there a better way to go about doing this?

Upvotes: 11

Views: 7694

Answers (2)

Kerry Liu
Kerry Liu

Reputation: 2162

Since document.elementFromPoint returns the topmost element, you'll need to temporarily set your draggable to display:none or pointer-events:none to find elements below it. I've created a gist below that returns a list of all elements at a given point.

try

var elementsArray = KoreSampl.atPoint(x,y,yourTableElement);

or

var elementsArray = KoreSampl.fromEvent(dropEvent, yourTableElement);

then

for(var i=0; i<elementsArray.length; i++) {
   //loop through elementsArray until you find the td you're interested in

}

Using the gist below: https://gist.github.com/2166393

;(function(){
    //test for ie: turn on conditional comments
    var jscript/*@cc_on=@_jscript_version@*/;
    var styleProp = (jscript) ? "display" : "pointerEvents";

    var KoreSampl = function() {};
    KoreSampl.prototype.fromEvent = function(e, lastElement) {
        e = e || window.event; //IE for window.event
        return this.atPoint(e.clientX, e.clientY, lastElement);
    };
    KoreSampl.prototype.atPoint = function(clientX, clientY, lastElement) {
        //support for child iframes
        var d = (lastElement) ? lastElement.ownerDocument : document;
        //the last element in the list
        lastElement = lastElement || d.getElementsByTagName("html")[0];

        var element = d.elementFromPoint(clientX, clientY);
        if(element === lastElement || element.nodeName === "HTML") {
            return [element];
        } else {
            var style= element.style[styleProp];
            element.style[styleProp]="none"; //let us peak at the next layer
            var result = [element].concat(this.atPoint(clientX,clientY,lastElement));
            element.style[styleProp]= style; //restore
            return result;
        }
    };
    window["KoreSampl"] = new KoreSampl();
})(); 

Upvotes: 19

user1031947
user1031947

Reputation: 6664

If you can dispense with older browsers, the following CSS will work:

Just apply this rule to your to your topmost element that is being dragged.

#dragging {
  pointer-events: none;
}

Upvotes: 10

Related Questions