如何防止可拖动的子元素相互重叠?

3
如何防止绝对定位的可拖动子元素相互重叠? 类似以下方式:
if( ($("#firstChild").position().left) >= ($("#secondChild").position().left) )
{
    $(this).draggable({ disabled: true });
}

但是这只能在停止拖动时禁用可拖动性,目标是以某种方式防止过度拖动...或者使用Droppable?有关CASE 2的任何想法吗?
编辑:此外,这是child1朝向child2的最大值,因此不会发生重叠,但是child1可以向右推child2,而child2可以向左推child1,重要的是不会发生重叠!

你能提供一个测试用例吗?我没有足够的时间收集所有相关的代码来创建一个测试用例。 - Rob W
@RobW,http://jsfiddle.net/ingol/rmaU2/ - Davor Zubak
请看这个链接... https://dev59.com/f0_Ta4cB1Zd3GeqPDsW0 - BMiner
@Rob W,我提供了测试用例,你有时间检查一下吗? - Davor Zubak
已经完成了可靠的代码编写,现在要构建一个答案。这里是示例:http://jsfiddle.net/rmaU2/90/ - Rob W
2个回答

2
你可以使用gamequery插件,它有碰撞检测功能。
另一种方法是:当你拖动元素时悬停在上面...就触发放置事件?这样他就永远无法把它拖到里面。创建一个类似于被拖动元素右侧的鼠标拖动位置,以确保不能将其拖到该元素内部。
希望你明白我的意思。
示例调用放置事件:
$('#rightbox').live('mouseenter', function(){
  $('#leftbox').droppable.option('drop');
});

类似这样的东西...没有测试过,但这是一个开始的方式


你有这个解决方案的任何示例吗? - Davor Zubak

1

在达到最佳解决方案之前/之前的一些注意事项:

  • 您已声明并初始化了allBetween变量,但未使用它。建议将其删除。
  • 在您的#buttonOne事件侦听器中,您正在使用不一致的值:429和424:if($("#firstInput").val() > 429 )$("#firstInput").val(424);
    1. 您多次使用#firstInput(和#thirdInput)选择器而没有缓存引用。
    2. 您正在为每个按钮复制函数。更好、更少出错的解决方案是创建一个方法来构建这些方法。

最终代码

优化已经在先前解释过了。我不会详细说明它们,因为那不是问题的主题。我已经在脚本注释中解释了所请求行为的函数逻辑(如下所示)。

$(document).ready(function() {
    // Helper to easily bind related events to the button.
    function createButtonClickEvent(sel_selector, input_selector, left_limit, right_limit) {
        return function(){
            var $sel = $(sel_selector),
                $input = $(input_selector),
                val = $input.val();
            if (val > right_limit) input.val(val = right_limit);
            else if (val < left_limit) input.val(val = left_limit);
            $sel.css('left', val + "px");

            var $allElems = $("#second").children(".single"),
                 $between = $allElems.inRangeX("#selFirst", "#selSecond");
            $allElems.removeClass("ui-selected");
            $between.addClass("ui-selected");
        }
    }
       //setValue 1
    $("#buttonOne").click(createButtonClickEvent("#selFirst", "#firstInput", 0, 429));    
    //setValue2
    $("#buttonTwo").click(createButtonClickEvent("#selSecond", "#thirdInput", 0, 429));


    //graph values
    var valuesG = [],
        $elements = $();
    for (i = 0; i < 144; i++) {
        valuesG[i] = Math.floor(Math.random() * (30 - 20 + 1) + 10);
        $elements = $elements.add($("<div class='single'>")
                             .css('height', valuesG[i])
                             .css('margin-top', 30 - valuesG[i]));
    }
    $elements.appendTo($("#second"));
    $("#second").children(".single").addClass("ui-selected");

    //inRangeX (http://stackoverflow.com/a/8457155/938089)
    (function($) {
        $.fn.inRangeX = function(x1, x2) {

            if (typeof x1 == "string" && +x1 != x1 || x1 instanceof Element) {
                x1 = $(x1);
            }
            if (typeof x2 == "string" && +x1 != x1 || x1 instanceof Element) {
                x2 = $(x2);
            }

            if (x1 instanceof $) {
                x1 = x1.offset().left;
            }
            if (x2 instanceof $) {
                x2 = x2.offset().left;
            }
            x1 = +x1;
            x2 = +x2;


            if (x1 > x2) {
                var x = x1;
                x1 = x2;
                x2 = x;
            }
            return this.filter(function() {
                var $this = $(this),
                    offset = $this.offset(),
                    rightSide = offset.left - 5;
                return offset.left >= x1 + 5 && rightSide <= x2;
            });
        }
    })(jQuery);

    //firstPositions
    var startFirst = $(".selector#selFirst").position().left;
    var startSecond = $(".selector#selSecond").position().left;
    $('input#firstInput').val(startFirst);
    $('input#thirdInput').val(startSecond);

    // *********** Actual requested code *********** //
    //first and second-Picker
    var $selFirst = $("#selFirst"),
        $selSecond = $("#selSecond"),
        cachedWidth = $selFirst.outerWidth();

    function drag_function(event, ui){
        var $firstRightBorder = $selFirst.position().left + cachedWidth,
             $secondLeft = $selSecond.position().left,
             diff = $firstRightBorder - $secondLeft;
        /*
         * The logic is as follows:
         * dif < 0 if selFirst and selSecond do not overlap
         * dif = 0 if they're next to each other
         * dif > 0 if they overlap each other
         * To fix this (reminder: if they overlap, dif is negative):
         * If current == #selFirst,
         *    left = left + dif
         * else (if current == #selSecond),
         *    left = left - dif
         */
        if (diff > 0) {
            var currentLeft = parseFloat($(this).css("left"));
            if (this.id == "selSecond") diff = -diff;
            ui.position.left = currentLeft - diff;
            ui.helper.css("left", currentLeft - diff);
        }
        var $allElems = $("#second").children(".single"),
            $between = $allElems.inRangeX("#selFirst", "#selSecond");
        $("#firstInput").val($("#selFirst").position().left);
        $("#thirdInput").val($("#selSecond").position().left);
        $allElems.removeClass("ui-selected");
        $between.addClass("ui-selected");
        var allBetween = $('.ui-selected');
    }

    $("#selFirst, #selSecond").draggable({
        containment: 'parent',
        axis: 'x',
        drag: drag_function,
        stop: drag_function
    });
}); //eof

我猜我来晚了,你已经找到了一个好的答案 ;) - Rob W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接