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

Javascript 如何防止可拖动的子元素相互拖动?,javascript,jquery,jquery-ui,collision-detection,jquery-ui-draggable,Javascript,Jquery,Jquery Ui,Collision Detection,Jquery Ui Draggable,如何防止可拖动的子元素在绝对位置相互拖动? 比如: if( ($("#firstChild").position().left) >= ($("#secondChild").position().left) ) { $(this).draggable({ disabled: true }); } 但这只会在停止拖动时禁用Dragable,目标是防止以某种方式过度包装…或使用Dropable 对案例2有什么想法吗 编辑: 另外,这是child1对child2的最大值,因此不会发生

如何防止可拖动的子元素在绝对位置相互拖动? 比如:

if( ($("#firstChild").position().left) >= ($("#secondChild").position().left) )
{
    $(this).draggable({ disabled: true });
}
但这只会在停止拖动时禁用Dragable,目标是防止以某种方式过度包装…或使用Dropable

对案例2有什么想法吗

编辑:


另外,这是child1对child2的最大值,因此不会发生重叠,但是child1可以将child2推到右侧,child2可以将child1推到左侧,重要的是没有重叠

您可以使用gamequery插件。有一个碰撞检测

您可以做的第二件事是:当您在拖动时悬停元素时。。。只是扣动扳机?所以他永远不能把它拖进去。在被拖动的元素的右侧设置类似于拖动鼠标的位置,这样您就可以确保无法在该元素内拖动鼠标

我希望你明白我的意思

呼叫丢弃示例:

$('#rightbox').live('mouseenter', function(){
  $('#leftbox').droppable.option('drop');
});

像这样的事。。。尚未进行测试,但这是一种在获得最佳解决方案之前先做一些注释的方法:

  • 您已声明并初始化了
    allBetween
    variablw,但未使用它。我建议把它去掉
  • #按钮none
    事件侦听器中,使用的值不一致:429和424:
    if($(“#firstInput”).val()>429)$(“#firstInput”).val(424)
    
  • 您多次使用
    #firstInput
    (和
    #thirdInput
    )选择器,而没有缓存引用
  • 您正在复制每个按钮的功能。一个更好、更不容易出错的解决方案是创建一个方法来构建这些方法
最终代码 优化已在前面解释过。我不会详细阐述,因为这不是问题的主题。我已经在脚本注释(下面)中解释了请求行为的功能逻辑

$(文档).ready(函数(){
//帮助器可以轻松地将相关事件绑定到按钮。
函数createButtonClickeEvent(选择选择器、输入选择器、左极限、右极限){
返回函数(){
变量$sel=$(sel_选择器),
$input=$(输入选择器),
val=$input.val();
如果(val>右极限)输入.val(val=右极限);
否则如果(val<左极限)输入.val(val=左极限);
$sel.css('left',val+“px”);
var$allegems=$(“#秒”)。子项(“.single”),
$between=$allegems.inRangeX(“#selFirst”、“#selsond”);
$ms.removeClass(“用户界面选定”);
$between.addClass(“所选ui”);
}
}
//设置值1
$(“#按钮无”)。单击(createButtonClickeEvent(“#selFirst“,“#firstInput”,0429));
//设置值2
$(“#按钮两”)。单击(createButtonClickEvent(“#selsond“,“#thirdInput”,0429));
//图形值
var valuesG=[],
$elements=$();
对于(i=0;i<144;i++){
valuesG[i]=Math.floor(Math.random()*(30-20+1)+10);
$elements=$elements.add($(“”)
.css('height',valuesG[i])
.css('margin-top',30-valuesG[i]);
}
$elements.appendTo($(“#秒”);
$(“#秒”).children(“.single”).addClass(“用户界面选中”);
//inRangeX(http://stackoverflow.com/a/8457155/938089)
(函数($){
$.fn.inRangeX=函数(x1,x2){
if(类型x1==“字符串”&&+x1!=x1 | | x1元素实例){
x1=$(x1);
}
if(类型x2==“字符串”&&+x1!=x1 | | x1元素实例){
x2=$(x2);
}
if(x1 instanceof$){
x1=x1.偏移量().左;
}
if(x2 instanceof$){
x2=x2.偏移量().左;
}
x1=+x1;
x2=+x2;
如果(x1>x2){
var x=x1;
x1=x2;
x2=x;
}
返回此.filter(函数(){
变量$this=$(this),
偏移量=$this.offset(),
右侧=偏移量。左侧-5;

return offset.left>=x1+5&&rightSide你有这个解决方案的例子吗?你能提供一个测试用例吗?我没有足够的时间收集所有相关的代码来创建一个测试用例。@RobW,检查一下…@Rob W,我提供了测试用例,你有时间检查一下吗?完成了创建可靠的代码,准备构建一个answ呃,现在,小提琴来了:我想我迟到了,你已经找到了一个好答案;)
$(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