如何防止可拖动的子元素相互拖延? [英] How to prevent draggable child elements from dragging over each other?

查看:96
本文介绍了如何防止可拖动的子元素相互拖延?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何防止可拖动的子元素在绝对位置上相互拖拽?
类似于:

How to prevent draggable child elements from dragging over each other in absolute position? Something like:

if( ($("#firstChild").position().left) >= ($("#secondChild").position().left) )
{
    $(this).draggable({ disabled: true });
}

但这只会在停止拖动时禁用拖拽,目标是阻止 overdragging 以某种方式......或者使用Droppable ???

but this only disables dragabble when stop dragging, the goal is to prevent from overdragging in some way...Or with Droppable???

CASE 2的任何想法?

Any ideas for CASE 2?

编辑:

此外,这是 child1 child2 的最大值,因此没有重叠,但 child1 可以在右侧推送 child2 child2 可以推送 child1 在左边,重要的是没有重叠的ocurrs!

Also, this is maximum for child1 towards child2 , so no overlap occurs, but child1 can push child2 on right, and child2 can push child1 on left, important thing is that no overlap ocurrs!

推荐答案

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

Some notes before / in order to reach the optimal solution:


  • 您已声明并初始化 allBetween variablw,但未使用它。我建议将其删除。

  • #buttonOne 事件监听器中,您使用的是不一致的值:429和424: if($(#firstInput)。val()> 429)$(#firstInput)。val(424);
  • You have declared and initialised the allBetween variablw, but not using it. I suggest to remove it.
  • At your #buttonOne event listener, you're using inconsistent values: 429 and 424: if($("#firstInput").val() > 429 )$("#firstInput").val(424);

  1. 您多次使用 #firstInput (和 #thirdInput )选择器而不缓存引用。

  2. 您正在复制每个按钮的功能。一个更好,更不容易出错的解决方案是创建一个方法来构建这些方法。

  1. You're using the #firstInput (and #thirdInput) selector multiple times without caching a reference.
  2. You're duplicating the functions for each button. A better, less error-prone solution is to create a method to build these methods.


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

The optimisations have been explained previously. I will not elaborate them, since that's not the topic of the question. I have explained the function logic of the requested behavior in the scripts comments (below).

$(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

这篇关于如何防止可拖动的子元素相互拖延?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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