HTML5拖放事件和setDragImage浏览器支持

时间:2012-10-07 04:23:27

标签: javascript html5 drag-and-drop cross-browser

我正在使用small jQuery plugin来模仿使用本机HTML5拖放事件的jQuery UI可拖动/可放置行为。

我想要添加的功能是能够指定将用作拖动代理的节点。

我做了一些研究,according to MDN要做到这一点,需要使用setDragImage(),传递图像或元素。
在不同浏览器中对setDragImage的支持是什么?

我注意到有一个名为jquery.event.drag的插件,它与我对此问题的预期不同。
此功能是否需要我像上面的插件一样进行某种解决方法,或者在使用setDragImage的大多数或所有浏览器中是否可以开箱即用?

修改

在使用此功能玩了一下后,似乎这个功能非常有限。

除了在相当多的浏览器中没有支持之外,使用任意DOM元素作为帮助器要求它在DOM树中是并且可见,因此你将元素本身放在主体上,以及它作为处理程序的副本。对于这种插件,这通常是不受欢迎的。

此外,即使满足正确的条款,渲染也是有问题的。尝试从<span>TEST</span>创建帮助程序时,帮助程序本身只显示一个白色矩形,其尺寸为span

这些问题是根据规格预期的吗?它们可以在代码中修复,还是需要解决方法?

1 个答案:

答案 0 :(得分:14)

setDragImage是IMO的重要功能,适用于任何非平凡的拖放用例。例如,考虑多选列表,其中拖动需要包括所有选择的项而不仅仅是拖动手势所在的行。奇怪的是你想要设置的东西需要在DOM中可见,但更糟糕的是,从版本11开始,IE中根本没有实现此方法。

但是,通过一些努力,我能够让它合理地令人满意地工作。可以在超时0函数中从DOM中删除自定义拖动图像节点。所以在dragstart中将它添加到DOM然后在设置拖动图像中使用它然后将其删除。这在FF中完美地工作,但在chrome中,拖动图像节点将在超时触发之前闪烁。防止这种情况的一种方法是将其定位为使得实际浏览器生成的拖动图像将出现在完全相同的位置,这并不像听起来那么糟糕,因为您可以控制自定义拖动图像相对于光标的位置。

我最近正在玩这个,并且能够让它在IE上工作。诀窍是让IE拖动自定义拖动图像节点而不是拖动启动的节点。您可以使用IE特定的dragDrop()方法执行此操作。

最后需要注意的是,在Windows上,自定义拖动图像节点的宽度有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");
});

});