HTML5 拖放事件和 setDragImage 浏览器支持 [英] HTML5 Drag and Drop events and setDragImage browser support

查看:25
本文介绍了HTML5 拖放事件和 setDragImage 浏览器支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 小型 jQuery 插件,它模仿原生的 jQuery UI 可拖动/可拖放行为HTML5 拖放事件.

I'm working on a small jQuery plugin that mimics the jQuery UI draggable/droppable behavior with native HTML5 drag and drop events.

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

A feature I'd want to add is the ability to specify the node which will serve as the drag proxy.

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

I did a bit of research, and according to MDN, to do this requires the use of setDragImage(), passing an image or an element.
What is the support for setDragImage in different browsers?

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

I've noticed there's a plugin named jquery.event.drag which takes a different than I expected to this problem.
Would this feature require me to make some kind of workaround like the above plugin, or should this be possible out-of-the-box in most or all browsers using setDragImage?

编辑

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

After playing around a bit with this functionality, it would seem that this function is quite limited.

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

Besides having no support in quite a few browsers, using an arbitrary DOM element as the helper requires it to be in the DOM tree and visible, and so you have the element itself on the body, and a copy of it as the handler. This is mostly unwanted for this sort of plugin.

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

Further more, rendering is also problematic even when the right terms are met. When trying to create a helper from <span>TEST</span>, the helper itself only showed a white rectangle with the dimensions of the span.

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

Are these issues that were to be expected according to the specs? Could they be fixed in code or would they require a workaround?

推荐答案

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

setDragImage is IMO a vital feature for any non trivial drag and drop use case. e.g consider a multi select list where a drag needs to include all the selected items and not just the row that the drag gesture was made on. it's odd that the thing you want to set needs to be visible in the DOM but even worse is that this method is not implemented at all in IE as of version 11.

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

However, with a bit of effort I was able to get it working reasonably satisfactorily. The custom drag image node can be removed from the DOM in a timeout 0 function. so add it to the DOM in dragstart then use it in set drag image and then remove it. This works perfectly in FF but in chrome the drag image node will flicker before the timeout fires. One way to prevent this is to position it such that the actual browser generated drag image will appear in exactly the same place, this is not as bad as it sounds since you can control the position of the custom drag image relative to the cursor.

我最近在玩这个,并且能够让它在 IE 上运行.诀窍是让 IE 拖动自定义拖动图像节点,而不是 dragstart 触发的节点.您可以使用 IE 特定的 dragDrop() 方法来做到这一点.

I was playing with this recently and was able to get it working on IE as well. the trick there is to get IE to drag the custom drag image node and not the node that dragstart fired on. you can do this with the IE specific dragDrop() method.

最后要注意的是,在 Windows 上,自定义拖动图像节点的宽度有 300 像素的限制,这适用于所有可拖动对象,而不仅仅是自定义节点.因此,如果拖动图像太大,浏览器会应用较重的径向渐变.

The final thing to be aware of is that on windows there is a 300px limit on the width of the custom drag image node this applies to all draggables not just the custom node actually. so the browser applies a heavy radial gradient if the drag image is too big.

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

});

这篇关于HTML5 拖放事件和 setDragImage 浏览器支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆