11

私は、jQuery UI のドラッグ可能/ドロップ可能な動作をネイティブの HTML5 ドラッグ アンド ドロップ イベントで模倣する小さな jQuery プラグインに取り組んでいます。

追加したい機能は、ドラッグ プロキシとして機能するノードを指定する機能です。

私は少し調査を行いましたが、 MDN によると、これを行うには を使用しsetDragImage()て画像または要素を渡す必要があります。さまざまなブラウザーで
のサポートは何ですか?setDragImage

jquery.event.dragという名前のプラグインがあることに気付きました。これは、この問題に対して予想とは異なる処理を行います。
この機能を使用するには、上記のプラグインのような何らかの回避策を講じる必要がありますsetDragImageか?それとも、.

編集

この機能を少し試してみると、この機能はかなり制限されているように見えます。

かなりの数のブラウザーでサポートされていないことに加えて、任意の DOM 要素をヘルパーとして使用するには、それがDOM ツリーにあり、可視である必要があるため、要素自体が本体にあり、そのコピーがハンドラーとして存在します。これは、この種のプラグインではほとんど不要です。

さらに、適切な条件が満たされている場合でも、レンダリングにも問題があります。からヘルパーを作成しようとすると<span>TEST</span>、ヘルパー自体は の寸法の白い長方形しか表示しませんでしたspan

これらの問題は、仕様上想定されていたものですか? コードで修正できますか、それとも回避策が必要ですか?

4

1 に答える 1

19

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");
});

});
于 2013-12-14T16:40:57.750 に答える