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");
});
});
概念和燦爛的解決方法的神奇的證明! – GeReV
此替代方法對於IE Edge仍然有效,該Edge並未實現setDragImage。 –