I'm trying to display ghost element instead of default browser preview for drag and drop. The problem is that in firefox image inside ghost element is not displayed while dragging. But if I drop it, and drag again the image is displayed.
So I think that this might be some sort of cache-related problem. But I can't see how I can pre-cache image in this case.
Here's the code:
//html:
<div class="parent container">
<img class="element" src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg" draggable="true" />
</div>
//js:
document.querySelector(".element").addEventListener("dragstart", function(e) {
var img = document.createElement("img");
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '100px';
div.style.position = 'fixed';
div.style.top = '-1000000px';
div.style.left = '-1000000px';
div.style.border = '2px solid red';
img.src = "http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg";
img.style.width = '100px';
img.style.height = '100px';
div.appendChild(img);
document.body.appendChild(div);
e.dataTransfer.setData('text/plain', 'test');
e.dataTransfer.setDragImage(div, 0, 0);
}, false);
Fiddle: https://jsfiddle.net/etseq5cg/5/
Steps to reproduce:
1) open fiddle/run snippet
2) try to drag sample image
Actual: you'll see an empty square with red border
Expected: square with image inside.
To reproduce it again you need to force-reload the page(ctrl+f5). That's why I think this is cache-ralated issue.
Note: I know that I should remove ghost element from DOM in dragend handler, but this is not important here.
Update:
1) the actual use-case includes view with big amount of images(~500), so it's not an option to pre-cache images via js.
2) For the ones who couldn't reproduce the issue, here's the screenshot: at first you see preview after hard reload(ctrl+f5), and then the second dragging attempt. Please note that no http requests are seen in network tab in web inspector in both cases.
Clear cookies and cache Sometimes problems loading websites can be fixed by clearing the cookies and cache. to open the menu panel. In the Time Range to clear: drop-down, select Everything. Below the drop-down menu, select both Cookies and Cache.
You can inspect and manage permissions for all domains on the about:permissions page. Select the first image link and use the cursor Down key to scroll through the list. If an image in the list is grayed and "Block Images from..." has a checkmark then remove this checkmark to unblock images from this domain.
To get the 'View Image' option back in your Firefox, you simply need to install a small add-on which you can download from mozilla.org. That's it! The add-on adds “View Image” in this context menu for images and restores the old functionality of opening the image in the same tab.
I cannot see the problem when I run your jsfiddle in Firefox 53 (on Windows 7). The ghost image and the dragged image have the same URL and the ghost image is always displayed when dragging. However, I can reproduce the problem with a ghost image that has a different URL.
You could add a hidden img
control to preload the ghost image. Something like this:
<div class="parent container">
<img class="element" draggable="true" src="http://the.element.image" />
<img class="imgGhost" src="http://the.ghost.image" />
</div>
According to my tests, these settings prevent the image preload in Firefox:
display: none
width: 0px
or height: 0px
)left: -10000px
)I also did not have much success with link prefetching. However, visibility: hidden
seems to work. The style of the hidden image element could be defined as:
.imgGhost {
position: absolute;
left: 0px;
top: 0px;
visibility: hidden;
}
The method can be tested for two draggable images in this jsfiddle. In the dragstart
event handler, the image URL is retrieved from the hidden element:
img.src = this.parentNode.querySelector(".imgGhost").src;
but it could be hard coded. If you prefer, you could set the src
attribute of the hidden image dynamically when the page is loaded. When testing in the jsfiddle, you can change the ghost image names (e.g. 225x225) before running it again, to make sure that the image was not cached.
You could also force a repaint of the layout after adding the div
control to the body
in the dragstart
event handler. This can be achieved by calling div.offsetHeight
:
div.appendChild(img);
document.body.appendChild(div);
div.offsetHeight; // Force repaint
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With