2017-05-04 31 views
16

我正在嘗試顯示ghost元素而不是默認瀏覽器預覽以進行拖放操作。問題在於,在拖動時不顯示ghost元素中的firefox圖像。但是,如果我放下它,並再次拖動圖像顯示爲Firefox在拖放幻影預覽中不顯示圖像

所以我認爲這可能是某種緩存相關的問題。但在這種情況下,我看不出預先緩存圖像的方式。

下面的代碼:

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

+0

您所遇到的問題是div追加到你的身體後,你的形象被載入。你可以使用'onload'來等待圖像加載,看看這個答案:http://stackoverflow.com/questions/12354865/image-onload-event-and-browser-cache。您可以在用戶拖動元素之前創建元素(在頁面加載時),因此您不必處理等待加載圖像的操作。 –

+0

@ toggy-tog-togs我不能等待圖像onload事件,因爲這是異步操作,並調用'setDragImage'是同步的。所以如果我在'onload'回調中調用'setDragImage',它不會做任何事情。 而且你可以看到圖像本身已經添加到DOM(我使用相同的圖像預覽和dnd鬼)。 – Rasalom

+0

我嘗試了Firefox中的jsfiddle。當我拖動「Sample」圖像時,我看到「Sample」重影圖像。 – ConnorsFan

回答

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控件添加到dragstart事件處理程序中的body之後,您也可以強制重新繪製佈局。這可以通過調用div.offsetHeight來實現:

div.appendChild(img); 
document.body.appendChild(div); 
div.offsetHeight; // Force repaint 
+0

能夠重現在* nix處的firefox 53上的OP中描述的問題。 – guest271314

+0

嗨,謝謝你的回答。我已經爲這個問題添加了「更新」部分,並以我得到的例子爲例。不幸的是,預先緩存圖像不是我的選擇。 – Rasalom

+0

如果使用[你的jsfiddle](https://jsfiddle.net/etseq5cg/5/)獲得屏幕截圖,我們必須有不同的配置。你在使用什麼操作系統?和哪個版本的Firefox?由於圖像已經顯示,所以應該可用。你有沒有RealPlayer插件(顯然,它可以[在重新加載圖像時導致麻煩](https://support.mozilla.org/en-US/kb/fix-problems-images-not-show#w_images-load-the負一時間但並非以後))? – ConnorsFan

1

css設置.parent僞類:hover.elementbackgroundurl("/path/to/image")<img class="element" src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/Sample.jpg" draggable="true" />父元素:hover抓取圖像。在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; 
 
}
<div class="parent container"> 
 

 
    <img class="element" src="http://www.thekrausemouse.com/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.net/etseq5cg/7/

相關問題