Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 817
Jordan Foreman Avatar asked Jan 10 '12 20:01

Jordan Foreman


2 Answers

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();
})(); 
like image 63
Kerry Liu Avatar answered Nov 09 '22 13:11

Kerry Liu


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;
}
like image 9
user1031947 Avatar answered Nov 09 '22 14:11

user1031947