setDragImage は、重要なドラッグ アンド ドロップの使用例にとって重要な IMO 機能です。たとえば、ドラッグジェスチャが行われた行だけでなく、選択されたすべてのアイテムをドラッグに含める必要がある複数選択リストを考えてみましょう。設定したいものがDOMで見える必要があるのは奇妙ですが、さらに悪いことに、バージョン11のIEではこのメソッドがまったく実装されていません.
しかし、少しの努力で、私はそれをかなり満足のいくように機能させることができました. カスタム ドラッグ イメージ ノードは、タイムアウト 0 関数で DOM から削除できます。そのため、dragstart で DOM に追加し、set drag image で使用してから削除します。これは FF では完全に機能しますが、クロムではタイムアウトが発生する前にドラッグ イメージ ノードがちらつきます。これを防ぐ 1 つの方法は、ブラウザで生成された実際のドラッグ イメージがまったく同じ場所に表示されるように配置することです。これは、カーソルに対するカスタム ドラッグ イメージの位置を制御できるため、思ったほど悪くはありません。
私は最近これで遊んでいて、IEでも動作させることができました。そこにある秘訣は、ドラッグスタートが起動したノードではなく、カスタム ドラッグ イメージ ノードを IE にドラッグさせることです。これは、IE 固有の dragDrop() メソッドで行うことができます。
最後に注意すべき点は、Windows では、カスタム ドラッグ イメージ ノードの幅に 300 ピクセルの制限があることです。これは、実際にはカスタム ノードだけでなく、すべてのドラッグ可能オブジェクトに適用されます。そのため、ドラッグ画像が大きすぎる場合、ブラウザーは強い放射状グラデーションを適用します。
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");
});
});