简体   繁体   English

jQueryUI放在最接近鼠标的目标上

[英]jQueryUI drop on target closest to mouse

I'm using jQueryUI's draggable and droppable interactions, and in my application I only want to allow a draggable to be dropped into a single drop target, ideally the target that is closest to the mouse, or the target that has the most overlap with the draggable. 我正在使用jQueryUI的可拖动和可拖放交互,在我的应用程序中,我只想允许将可拖动对象拖放到单个放置目标中,理想情况下是最接近鼠标的目标,或者与鼠标重叠最多的目标拖动。 The problem is that my drop targets can sometimes be close together, and it is very possible that a draggable will overlap more than one drop target. 问题是我的放置目标有时可能靠近在一起,并且可拖动对象很可能会重叠多个放置目标。 When my draggable overlaps more than one drop target, I'd like to set the hoverClass on only one of the drop targets, and only allow the drop on that target. 当我的可拖动对象与多个放置目标重叠时,我只想在其中一个放置目标上设置hoverClass,并且只允许在该目标上放置。 Is this possible with jQueryUI? jQueryUI有可能吗?

I like the behavior of the 'touch' tolerance, so I'd like to keep that if possible. 我喜欢“触摸”容差的行为,因此,如果可能的话,我希望保持这种状态。 Here is a jsfiddle that demonstrates the problem I'm trying to solve: http://jsfiddle.net/gDkAQ/2/ 这是一个jsfiddle,它演示了我要解决的问题: http : //jsfiddle.net/gDkAQ/2/

$('.draggable').draggable();

$('.droppable').droppable({
    tolerance: 'touch',
    hoverClass: 'drop-acceptable',
    drop: function(event, ui) {
        $(this).css({ 'background-color': '#00f' });
    }
});

There is another library from ThreeDubMedia that provides the exact feature I'm looking for (the "overlap" tolerance mode), but unfortunately that library only seems to work with absolute-positioned elements, so I don't think it would work in my application. ThreeDubMedia提供了另一个库,它提供了我正在寻找的确切功能(“重叠”公差模式),但不幸的是,该库似乎只适用于绝对定位的元素,因此我认为它无法在我的作品中使用应用。

I came up with a solution, but it involves fragile duck punching of jQueryUI. 我想出了一个解决方案,但它涉及到jQueryUI的易碎鸭子打孔。 There is an internal function called $.ui.intersect that determines if a draggable can be dropped onto a droppable. 有一个内部函数称为$.ui.intersect ,它确定是否可以将可拖动对象拖放到可放置对象上。 There is also a $.ui.ddmanager.droppables collection that contains a list of all droppables on the page. 还有一个$.ui.ddmanager.droppables集合,其中包含页面上所有可放置对象的列表。 I overrode the intersect function to support a 'touch-closest-to-mouse' toleranceMode that finds the closest droppable to the mouse, and only returns true if the current droppable is the closest. 我覆盖了intersect函数以支持“ touch-closest-to-mouse” toleranceMode,它找到与鼠标最接近的可放置对象,并且仅在当前可放置对象最接近时才返回true。 Here is the solution I came up with: 这是我想出的解决方案:

(function () {
    var defaultIntersect = $.ui.intersect;
    var cursorX, cursorY;

    $(document).mousemove(function (e) {
        cursorX = e.pageX;
        cursorY = e.pageY;
    });

    $.ui.intersect = function (draggable, droppable, toleranceMode) {
        if (toleranceMode !== 'touch-closest-to-mouse') {
            return defaultIntersect(draggable, droppable, toleranceMode);
        }
        if (!defaultIntersect(draggable, droppable, 'touch')) {
            return false;
        }
        var acceptable = _.filter($.ui.ddmanager.droppables.default, function (d) {
            return defaultIntersect(draggable, d, 'touch');
        });
        var closest = _.min(acceptable, function (other) {
            var otherCenterX = other.offset.left + other.proportions().width / 2;
            var otherCenterY = other.offset.top + other.proportions().height / 2;
            return Math.sqrt(Math.pow(otherCenterX - cursorX, 2) + Math.pow(otherCenterY - cursorY, 2));
        });
        return droppable === closest;
    };

    $('.draggable').draggable();

    $('.droppable').droppable({
        tolerance: 'touch-closest-to-mouse',
        hoverClass: 'drop-acceptable',
        drop: function (event, ui) {
            $(event.target).css({
                'background-color': '#0f0'
            });
        }
    });
})();

This works with jQueryUI 1.10.4. 这适用于jQueryUI 1.10.4。 Here is a jsfiddle with the working solution: http://jsfiddle.net/gDkAQ/12/ 这是具有工作解决方案的jsfiddle: http : //jsfiddle.net/gDkAQ/12/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM