admin管理员组文章数量:1287698
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=".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 = ".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: /
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.
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./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./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/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.
Share Improve this question edited May 12, 2017 at 15:17 Rasalom asked May 4, 2017 at 14:25 RasalomRasalom 3,1113 gold badges22 silver badges29 bronze badges 4-
The problem you are having is your image is being loaded after the div is appended to your body. You can use image
onload
to wait for the image to load, take a look at this answer: stackoverflow./questions/12354865/…. You could instead create the element before the user drags the element (on page load) so you shouldn't have to deal with waiting for the image to load. – Peter Dempsey Commented May 4, 2017 at 14:43 - @toggy-tog-togs I can't wait for image onload event because this is async operation and calling 'setDragImage' is sync. So if I call 'setDragImage' inside 'onload' callback it wont do anything. And as you can see the image itself is already added to the DOM(I use same image for preview and dnd ghost). – Rasalom Commented May 4, 2017 at 14:57
- I tried the jsfiddle in Firefox. When I drag the "Sample" image, I see the "Sample" ghost image. – Martin Parenteau Commented May 10, 2017 at 13:17
- @ConnorsFan I've added 'Update' section with screenshots of what i'm getting. – Rasalom Commented May 12, 2017 at 15:20
2 Answers
Reset to default 7 +50I 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:
- Hiding the element with
display: none
- Setting a null size (
width: 0px
orheight: 0px
) - Moving it outside of the viewport (e.g.
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.
According to your ment, preloading the image is not an option. And you are using the same image URL for the dragging ghost image. In that case, you could check this page to see if any option is preventing the reload of the image.
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
At css
set .parent
pseudo class :hover
and .element
background
to url("/path/to/image")
to fetch image at :hover
of <img class="element" src="http://www.thekrausemouse./wp-content/uploads/2016/03/Sample.jpg" draggable="true" />
parent element. At dragstart
event set div
.className
to "element"
.
.element {
width: 100px;
height: 100px;
background: url("http://www.thekrausemouse./wp-content/uploads/2016/03/Sample.jpg");
background-size: 100px 100px;
}
.parent:hover {
background: url("http://www.thekrausemouse./wp-content/uploads/2016/03/Sample.jpg");
background-size: 0px 0px;
}
<div class="parent container">
<img class="element" src="http://www.thekrausemouse./wp-content/uploads/2016/03/Sample.jpg" draggable="true" />
</div>
<script>
function handleImage(e) {
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';
div.className = "element";
document.body.appendChild(div);
e.dataTransfer.setData('text/plain', 'test');
e.dataTransfer.setDragImage(div, 0, 0);
}
document.querySelector(".element")
.addEventListener("dragstart", handleImage, false);
</script>
jsfiddle https://jsfiddle/etseq5cg/7/
本文标签: javascriptFirefox is not displaying image in drag and drop ghost previewStack Overflow
版权声明:本文标题:javascript - Firefox is not displaying image in drag and drop ghost preview - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741321545a2372231.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论