SortableJS / Sortable

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
https://sortablejs.github.io/Sortable/
MIT License
29.6k stars 3.7k forks source link

Cannot drop over iframe (not into - but absolutely on top of an iframe) #1388

Open dolbex opened 5 years ago

dolbex commented 5 years ago

Hey guys, I ran into a really weird bug in Chrome when you are sorting OVER an iframe via absolute positioned containers. You can start drag just fine but the dropzone is somehow "under" the iframe even though z-index is clearly in order.

See the following pen for example:

https://codepen.io/dolbex/pen/WYpPMq

lokesh commented 5 years ago

I've run into this issue as well but I suspect it has to do with Chrome changing how it handles UI events when they occur over iframes with cross-origin content. Here is a jsfiddle that tests drag event firing over two iframes, one with content from another domain and one with local content. Take a look at the console to track the drag events.

https://jsfiddle.net/lokesh/fsb7kdny/

owen-m1 commented 5 years ago

It seems to be an issue localized to drag and drop. For now you can use forceFallback: true.

lokesh commented 5 years ago

Thanks @owen-m1 for the quick response. I'll enable forceFallback and see if that resolves the issue I'm seeing in Chrome v70 and greater.

lokesh commented 5 years ago

I was able to use the forceFallback option to fix the issue where the sortable action was not working in Chrome 70+ when done in a modal that was positioned over an iframe that contained content from a different domain. Thanks for the help!

frutality commented 5 years ago

When I added forceFallback, I discovered that when I'm dragging element over an iframe, UI becomes slow and glitchy. It becomes really hard to sort elements containing iframes. So I added a workaround: transparent absolutely positioned div with 100% width and height, that is "visible" only when user is dragging something.

Simplified markup:

<div>
    <iframe src="..."></iframe>
    <div class="workaround"></div>
</div>

.workaround{
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
    z-index: 10; /* this should be adjusted depending on your needs */
}

I skipped code responsible for hiding/showing workaround block, because it is very dependent on your framework and situation.

dolbex commented 5 years ago

I like that fix @frutality - Not too hacky and hey, gotta do whatcha gotta do when Chrome isn't behaving. :)

imrene868 commented 5 years ago

Wow, and here I've been trying to figure out why I couldn't sort when a few seemingly unrelated conditions were met. Spent an entire 3 days trying to figure this out and then I realized that this bug is actually relevant to me and the actual cause.

theo-staizen commented 2 years ago

Just run into this issue in Chrome 99. Setting pointer-events: none on iframes while dragging also works. No need for additional elements to mask the iframe. This is our workaround

return Sortable.create(element, {
  onChoose: () => document?.body?.classList.add('sortable-dragging'),
  onUnchoose: () => document?.body?.classList.remove('sortable-dragging')
});

then the css, which applies globally is this

body.sortable-dragging iframe {
  pointer-events: none;
}

Perhaps something similar could be done by default or via an option (e.g disableIframesOnDrag)?