Firefox不会在拖放幻影预览

时间:2017-05-04 14:25:49

标签: javascript html 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>

// 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);

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

重现的步骤:

1)打开小提琴/跑步片段

2)尝试拖动样本图像

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

预期:内部有图像正方形。

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

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

更新:

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

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

2 个答案:

答案 0 :(得分:7)

我在Firefox 53(在Windows 7上)运行your 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>

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

  • 使用display: none
  • 隐藏元素
  • 设置空尺寸(width: 0pxheight: 0px
  • 将其移出视口(例如left: -10000px

link prefetching我也没有取得太大成功。但是,visibility: hidden似乎有效。隐藏图像元素的样式可以定义为:

.imgGhost {
    position: absolute;
    left: 0px;
    top: 0px;
    visibility: hidden;
}

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

img.src = this.parentNode.querySelector(".imgGhost").src;

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

<小时/> 根据您的评论,预装图像不是一种选择。并且您使用相同的图像URL来拖动重影图像。在这种情况下,您可以检查this page以查看是否有任何选项阻止重新加载图片。

在将div控件添加到body事件处理程序中的dragstart后,您还可以强制重新布局布局。这可以通过调用div.offsetHeight

来实现
div.appendChild(img);
document.body.appendChild(div);
div.offsetHeight; // Force repaint

答案 1 :(得分:2)

css设置.parent伪类:hover.element backgroundurl("/path/to/image"),以:hover的{​​{1}}获取图片{1}}父元素。在<img class="element" src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg" draggable="true" />事件集dragstart div.className

"element"
.element {
  width: 100px;
  height: 100px;
  background: url("http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg");
  background-size: 100px 100px;
  
}

.parent:hover {
  background: url("http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg");
  background-size: 0px 0px;
}

jsfiddle https://jsfiddle.net/etseq5cg/7/