7

我正在使用 JQuery UI 来实现可调整大小/可拖动的元素。现在我想为这些元素定义一个容器,限制在三个(!)边上调整大小/拖动。例如,看看这个JSFiddle 示例。您可以看到包含的元素只能在父区域内调整大小/拖动。

我想要实现的是元素可以超过底部阈值并移动到父元素的底部边框之外。尽管如此,调整大小/拖动仍应限制在顶部、右侧和左侧,如父级相应边界所规定的那样。

所以这个修改是我想出的:

// resizable/draggable option
resize/drag : function(event, ui) {
    expandParent("#parentElement", "#dragElement");
}

function expandParent(parentName, childName) {
    var dragEl = $(childName);
    var dragElTop = parseInt(dragEl.css("top"), 10);
    var dragElHeight = parseInt(dragEl.css("height"), 10);
    var dragElBottom = dragElTop + dragElHeight;
    var parentEl = $(parentName);
    var parentElBottom = parseInt(parentEl.css("height"));
    if(parentElBottom <= dragElBottom + 20) {
        parentEl.css("height", "+=2");
    }
}

如果您玩弄底部边框,您会注意到如果子级离父级的底部边框太近,父级的区域会扩大。不幸的是,这在 20 像素后停止。然后,您必须释放鼠标按钮并再次调整大小/拖动以进一步扩展该区域。你知道这是为什么吗?

4

4 回答 4

5

好吧,expandParent 函数不会起作用,因为 JQuery UI 已经设置了容器边界,并且在您释放鼠标之前它不会更新。

所以我可以想到两种解决方案,一种很优雅,另一种很棘手

显然,优雅的解决方案是编写自己的包含方法,该方法在底部是免费的。

但是现在我有一个棘手的解决方案,方法是使用一个虚拟父元素并将其高度设置为一个较大的值,如 1000 或窗口高度,然后为真正的父元素设置溢出隐藏属性。

这是我的解决方案:

<div id="parentElement">
    <div id="dummy-parent">
        <div id="dragElement" class="dragClass">
            <p>Drag me around!</p>
        </div>
    </div>
</div>



function expandParent(parentName, childName) {
    var dragEl = $(childName);
    var parentEl = $(parentName);
    var dragElHeight=dragEl.height();
    if(parentEl.height() <= dragElHeight) {
        parentEl.height(dragElHeight);
    }
}

检查 JS 小提琴

您必须根据您的应用程序修改代码我刚刚给您的想法

于 2013-07-15T18:50:20.063 回答
2

看起来在 JQuery UI 内部,它们在拖动开始时保留父级的信息,因此即使您更改大小,它仍然会限制拖动。

要解决此问题,您可以设置自己的包含边界框。

$("#dragElement")
    .draggable({
        cursor      : "move",
        scroll      : false,
        containment : [20, 20, 400+20, 1000],
        drag : function(event, ui) {
            expandParent("#parentElement", "#dragElement");
        }
    })
    .resizable({
        containment : "parent",
        resize : function(event, ui) {
            expandParent("#parentElement", "#dragElement");
        }
    });

function expandParent(parentName, childName) {
    var dragEl = $(childName);
    var dragElTop = parseInt(dragEl.css("top"), 10);
    var dragElHeight = parseInt(dragEl.css("height"), 10);
    var dragElBottom = dragElTop + dragElHeight;
    var parentEl = $(parentName);
    var parentElBottom = parseInt(parentEl.css("height"));
    if(parentElBottom <= dragElBottom + 20) {
        parentEl.css("height", dragElBottom+20);
    }
}

使用上面的代码,它将允许父级的高度调整为 1000+20。你可以在这里尝试上面的代码(JSFiddle)尝试上面的代码。

如果需要做一个动态容器,在开始时(以及在 resize 方法中),使用正确的 BoundingBox 设置新容器。

var p = $("#parentElement");
var dragWidth = parseInt($("#dragElement").css('width'));
var left = p[0].offsetLeft;
var top = p[0].offsetTop;
var width = parseInt(p.css("width"), 10)-dragWidth;
var containment = [left, top, width+left, 1000];

是的,我知道解决方案有点骇人听闻.. 但无论如何,我刚刚更新了JSFiddle这个解决方案可能不是动态计算和重新设置容器的大小。只是想让 JSFiddle 工作得很好。

于 2013-07-15T17:52:05.953 回答
0
    $("#dragElement")
        .draggable({
            cursor      : "move",
            containment : '#Container',
            drag : function(event, ui) {
                var growAmount = 10;
                var cont = $('#Container');
                var item = $(ui.helper);

                var itemOffset = item.offset();
                itemOffset.bottom = itemOffset.top + dProps.item.height();


                var contOffset= cont.offset();
                contOffset.bottom = contOffset.top + cont.height();

                if(itemOffset.bottom >= contOffset.bottom){
                    var inst = item.draggable("instance");
                    inst.containment = [inst.containment[0], inst.containment[1], inst.containment[2], inst.containment[3] + growAmount];
                    cont.height(parseInt(cont.height()) + growAmount);
                }
            }
        });
于 2014-08-14T16:03:59.267 回答
0

好的,所以这是可能的,但不是没有 shinanigans ......

基本上,jQuery 的可拖动对象接受的包含数组参数只会限制提供的值。通常,数组与 [x1, y1, x2, y2] 相关,因此如果我们只提供前 3 个,而未定义第 4 个,则底部将不受约束。

但是,这意味着我们需要手动提供 left、top 和 right 值。顶部和左侧很容易,但必须计算右侧:

var scrollbarWidth = 22;
var container = $('#my-container');
var cOffset = container.offset();
var cRight = cOffset.left + c.outerWidth() - $('#my-draggable').outerWidth() - scrollbarWidth; 

$('#my-draggable').draggable({
  containment: [ cOffset.left, cOffset.top, cRight ],
  scroll: true
});

这将很好地开始,但是......这是踢球者,每次容器移动时,可拖动元素都必须更新它的包含属性。此外,如果调整窗口大小,这也可能是一个问题。也就是说,我这里确实有一个功能齐全的示例。

于 2019-03-19T02:12:52.353 回答