Firefox不会在拖放幻影预览中显示图像

Ras*_*lom 16 html javascript css firefox drag-and-drop

我正在尝试显示ghost元素而不是拖放的默认浏览器预览.问题是在拖动时不显示ghost元素内的ghost元素.但是,如果我放下它,再次拖动图像就会显示出来.

所以我认为这可能是某种与缓存相关的问题.但在这种情况下,我无法看到如何预先缓存图像.

这是代码:

// HTML:

<div class="parent container">
<img class="element" src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg" draggable="true" />
</div>
Run Code Online (Sandbox Code Playgroud)

// 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);
Run Code Online (Sandbox Code Playgroud)

小提琴:https: //jsfiddle.net/etseq5cg/5/

重现步骤:

1)打开小提琴/运行片段

2)尝试拖动样本图像

实际:你会看到一个带红色边框的空方块

预期:里面有图像的方形.

要再次重现它,您需要强制重新加载页面(ctrl + f5).这就是为什么我认为这是缓存相关的问题.

注意:我知道我应该在dragend处理程序中从DOM中删除ghost元素,但这在这里并不重要.

更新:

1)实际用例包括具有大量图像(~500)的视图,因此不能通过js预先缓存图像.

2)对于那些无法重现问题的人,这里是截图:首先你看到硬重载后的预览(ctrl + f5),然后是第二次拖动尝试.请注意,在这两种情况下,Web检查器中的网络选项卡中都没有看到http请求.截图

Con*_*Fan 7

我在Firefox 53(在Windows 7上)运行你的jsfiddle时看不到问题.重影图像和拖动的图像具有相同的URL,并且在拖动时总是显示重影图像.但是,我可以使用具有不同URL的重影图像重现该问题.

您可以添加隐藏img控件来预加载重影图像.像这样的东西:

<div class="parent container">
    <img class="element" draggable="true" src="http://the.element.image" />
    <img class="imgGhost" src="http://the.ghost.image" />
</div>
Run Code Online (Sandbox Code Playgroud)

根据我的测试,这些设置会阻止Firefox中的图像预加载:

  • 隐藏元素 display: none
  • 设置空值(width: 0pxheight: 0px)
  • 将其移到视口外(例如left: -10000px)

链接预取我也没有太大的成功.但是,visibility: hidden似乎工作.隐藏图像元素的样式可以定义为:

.imgGhost {
    position: absolute;
    left: 0px;
    top: 0px;
    visibility: hidden;
}
Run Code Online (Sandbox Code Playgroud)

该方法可以在这个jsfiddle中测试两个可拖动的图像.在dragstart事件处理程序中,从隐藏元素中检索图像URL:

img.src = this.parentNode.querySelector(".imgGhost").src;
Run Code Online (Sandbox Code Playgroud)

但它可能是硬编码的.如果您愿意,可以在src加载页面时动态设置隐藏图像的属性.在jsfiddle中进行测试时,您可以在再次运行之前更改重影图像名称(例如225x225),以确保图像未被缓存.


根据您的评论,预装图像不是一种选择.并且您使用相同的图像URL来拖动重影图像.在这种情况下,您可以检查此页面以查看是否有任何选项阻止重新加载图像.

你也可以强制布局的重绘加入后div控制到bodydragstart事件处理程序.这可以通过调用div.offsetHeight:

div.appendChild(img);
document.body.appendChild(div);
div.offsetHeight; // Force repaint
Run Code Online (Sandbox Code Playgroud)