2012-10-07 114 views
9

我正在研究small jQuery plugin,它模仿了使用本機HTML5拖放事件的jQuery UI可拖放/放置行爲。HTML5拖放事件和setDragImage瀏覽器支持

我想要添加的一個功能是能夠指定將用作拖動代理的節點。

我做了一些研究,並according to MDN,要做到這一點需要使用setDragImage(),傳遞一個圖像或元素。
在不同的瀏覽器中支持setDragImage是什麼?

我注意到有一個名爲jquery.event.drag的插件,它採用與我預期的不同的問題。
這個功能是否需要我做出一些類似上述插件的解決方法,或者應該可以在大多數或所有使用setDragImage的瀏覽器中開箱即用?

編輯

圍繞這個功能有點打後,它似乎是這個功能是相當有限的。

除了在不少瀏覽器中沒有支持,使用任意DOM元素作爲幫助程序,它需要在DOM樹中顯示爲,並且可見,因此您將元素本身放在主體上,它作爲處理程序。這對於這種插件來說大多是不需要的。

此外,即使滿足正確的條件,渲染也是有問題的。當試圖從<span>TEST</span>創建助手時,助手本身只顯示一個尺寸爲span的白色矩形。

這些問題是根據規格預期的嗎?他們可以在代碼中修復還是需要解決方法?

回答

10

setDragImage是IMO對於任何非平凡的拖放用例的重要特性。例如,考慮一個多選列表,其中拖動需要包括所有選定的項目,而不僅僅是拖動手勢所在的行。奇怪的是,你想要設置的東西需要在DOM中可見,但更糟糕的是,該方法在版本11中根本沒有實現。

但是,通過一點努力,我能夠讓它工作得合理令人滿意。自定義拖動圖像節點可以在超時0功能中從DOM中刪除。因此將其添加到dragstart中的DOM,然後在設置的拖動圖像中使用它,然後將其刪除。這在FF中完美工作,但在Chrome中,拖動圖像節點將在超時觸發前閃爍。防止這種情況的一種方法是將其定位,使得實際瀏覽器生成的拖動圖像將顯示在完全相同的位置,這並不像聽起來那麼糟糕,因爲您可以控制自定義拖動圖像相對於光標的位置。

我最近在玩這個遊戲,並且能夠在IE上運行它。訣竅是讓IE拖動自定義拖動圖像節點,而不是拖動開啓的節點。你可以使用IE特定的dragDrop()方法來做到這一點。

最後要注意的是,在窗口上自定義拖拽圖像節點的寬度有一個300px的限制,這適用於所有可拖拽的,不僅僅是實際的自定義節點。因此如果拖動圖像太大,瀏覽器會應用較大的徑向漸變。

http://jsfiddle.net/stevendwood/akScu/21/

$(function() { 

(function($) { 
    var isIE = (typeof document.createElement("span").dragDrop === "function"); 
    $.fn.customDragImage = function(options) { 

     var offsetX = options.offsetX || 0, 
      offsetY = options.offsetY || 0; 

     var createDragImage = function($node, x, y) { 
      var $img = $(options.createDragImage($node)); 
      $img.css({ 
       "top": Math.max(0, y-offsetY)+"px", 
       "left": Math.max(0, x-offsetX)+"px", 
       "position": "absolute", 
       "pointerEvents": "none" 
      }).appendTo(document.body); 

      setTimeout(function() { 
       $img.remove(); 
      }); 

      return $img[0]; 
     }; 

     if (isIE) { 
      $(this).on("mousedown", function(e) { 
       var originalEvent = e.originalEvent, 
        node = createDragImage($(this), originalEvent.pageX, originalEvent.pageY); 

       node.dragDrop(); 
      }); 
     } 

     $(this).on("dragstart", function(e) { 

      var originalEvent = e.originalEvent, 
       dt = originalEvent.dataTransfer; 

      if (typeof dt.setDragImage === "function") { 
       node = createDragImage($(this), originalEvent.pageX, originalEvent.pageY); 
       dt.setDragImage(node, offsetX, offsetY); 
      } 
     }); 

     return this; 
    }; 
}) (jQuery); 



$("[draggable='true']").customDragImage({ 
    offsetX: 50, 
    offsetY: 50, 
    createDragImage: function($node) { 
     return $node.clone().html("I'm a custom DOM node/drag image").css("backgroundColor", "orange"); 
    } 
}).on("dragstart", function(e) { 
    e.originalEvent.dataTransfer.setData("Text", "Foo"); 
}); 

}); 
+1

概念和燦爛的解決方法的神奇的證明! – GeReV

+1

此替代方法對於IE Edge仍然有效,該Edge並未實現setDragImage。 –