我正在使用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像素后停止。然后,您必须释放鼠标按钮并再次调整大小/拖动以进一步扩展该区域。你知道为什么吗?
好吧,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 Fiddle
你必须根据你的应用程序修改代码,我刚刚给了你
在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)。
如果需要创建动态容器,请在开始时(以及在调整大小方法中)使用正确的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];
是的,我知道这个解决方案有点粗糙。。但无论如何,我只是更新了JSFiddleThis解决方案可能不是动态计算和重新设置容器的大小。只是想让一个JSFiddle工作得很好。
$("#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);
}
}
});
好的,所以这是可能的,但没有shinanigans。。。
基本上是jQuery的draggable所接受的containment数组参数,将仅限于所提供的值。通常,数组与到[x1,y1,x2,y2],所以如果我们只提供前3个,并保留第4个未定义,则底部将不受约束。
但是,这意味着我们需要手动提供左侧、顶部和正确的价值观。顶部和左侧很容易,但右侧必须计算:
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
});
这一开始会很好,但是。。。这是踢球者,每次容器移动时,可拖动元素必须具有其containment属性更新。此外,如果调整窗口大小,这也可能是一个问题。那个说,我这里确实有一个功能齐全的例子。