2

I ran into a drag and drop issue in Google Chrome:

foo.html :

<iframe style="position:absolute;left:300px" src="bar.html"></iframe>

bar.html :

<div draggable="true" id="bar">Drag me!</div>
<script>
    document.getElementById("bar").addEventListener("dragend", function(e) {
        console.log(e.view === window); // false
        console.log(e.view === window.parent); // true
    });
</script>

Why is e relative to the parent window rather than the current window (ie the window property of the current frame)? I've confirmed that dragstart and dragover both receive arguments with view properties relative to the current frame.

Here's a jsfiddle that reproduces the issue on safari or chrome.

EDIT: To clarify - in my tests, I am NOT ending drag outside of the frame.

Brian Gradin
  • 1,845
  • 16
  • 35
  • can you state what the output should be compared to what it's outputting now? – A. L May 24 '17 at 03:50
  • what is your expected output? – Shivani Shanishchara May 24 '17 at 14:17
  • Your dragstart always occurs within the iframe and hence e.view will always equal the iframe's window for dragstart. However, when you drag out of the iframe boundaries, the dragend will now be outside of the iframe and hence the e.view will equal whatever window you happen to drop it into that is a parent of the iframe. The e.clientX and e.clientY positions for the dragend will be accurate for the parent window in this case. – fmacdee May 24 '17 at 17:47
  • @fmacdee I added a clarification – Brian Gradin May 24 '17 at 19:52

2 Answers2

0

The reason the parent window is stored in e.view is because the dragend is happening outside of the iframe. If you want to know where the iframe is relative to the window then you can do that as long as both files are on the same server so there are no cross origin issues protecting the parent window. If this is true, then you can do the following:

// get the iframes from the parent
var iframes = window.parent.document.getElementsByTagName('iframe');
var iframe;

// search through the iframes[] array and match your name 
for (var i = 0; i < iframes.length; i++) {
    if (iframes[i].src == 'bar.html') { // note, you may have to parse this or add your full pathname
        iframe = iframes[i];
        break;
    }
}
// get the boundaries of the selected iframe
var rect = iframes[i].getBoundingClientRect();

After this, when you process dragend events, do the following:

if(e.view == window) {
    xoff = e.clientX;
    yoff = e.clientY;
}
else {
    xoff = e.clientX - rect.left;
    yoff = e.clientY - rect.top;
}

That will give you the x and y positions relative to the iframe.

fmacdee
  • 2,153
  • 6
  • 14
0

if 'ondragend' event is triggered outside of the iframe the event gets bubbled to the active document that contains the iframe ....

browsers block scripts trying to access a frame with a different origin because of security reasons ....

some useful info about the security in this thread

If you are working on the backend aswell try posting the clientX,clientY values to the backend when ondragstart fires & rendering your desired page to then get the relative position when dragend fires ...

Gal Ratzkin
  • 114
  • 2
  • 8