【问题标题】:HTML5 Drag and Drop events and setDragImage browser supportHTML5 拖放事件和 setDragImage 浏览器支持
【发布时间】:2012-09-27 18:45:33
【问题描述】:

我正在开发一个small jQuery plugin,它通过原生 HTML5 拖放事件模拟 jQuery UI 可拖放/可拖放行为。

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

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

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

编辑

在玩了一会儿这个功能之后,似乎这个功能非常有限。

除了在相当多的浏览器中不支持之外,使用任意 DOM 元素作为 helper 要求它在 DOM 树中并且可见,因此您将元素本身放在主体上,并将其副本作为处理程序。这对于这类插件来说是最不需要的。

此外,即使满足正确的条件,渲染也存在问题。在尝试从<span>TEST</span> 创建助手时,助手本身只显示一个白色矩形,其尺寸与span 相同。

这些问题是否符合规范?它们可以在代码中修复还是需要解决方法?

【问题讨论】:

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


    【解决方案1】:

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

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

    我最近在玩这个,并且能够让它在 IE 上运行。诀窍是让 IE 拖动自定义拖动图像节点,而不是 dragstart 触发的节点。您可以使用 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");
    });
    
    });
    

    【讨论】:

    • 出色的概念证明和出色的解决方法!
    • 这个变通方法对 IE Edge 仍然有效,它也没有实现 setDragImage。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2011-02-10
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2013-12-03
    相关资源
    最近更新 更多