我有一个可以将包含设置为父级的可拖动元素。这很有效,但div内容可以改变,使其更高。无论如何都要触发拖动事件,以确保它不会从其父内部移动。现在,它可以与父项重叠,直到它被拖动,然后收容开始。
最诚挚的问候 标记
答案 0 :(得分:10)
我已经实现了一个小插件,可以满足您的需求。它可以在可拖动的更改大小之后强制执行包含,甚至可以在您拖动时进行操作。我已经使用jQuery UI 1.8.6和jQuery 1.4.3测试了它,但它可能会破坏过去或未来的版本,因为它必须使用内部方法。
/*
* jQuery UI RefreshContainment v0.1
*
* A plugin for jQuery UI's Draggable. It adds a refreshContainment method to
* every draggable which allows you to use the containment option on draggables
* with dynamically changing sizes.
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.mouse.js
* jquery.ui.draggable.js
*/
(function ($){
var $window = $(window);
// We need to know the location of the mouse so that we can use it to
// refresh the containment at any time.
$window.data("refreshContainment", {mousePosition: {pageX: 0, pageY: 0}});
$window.mousemove(function (event) {
$window.data("refreshContainment", {
mousePosition: {pageX: event.pageX, pageY: event.pageY}
});
});
// Extend draggable with the proxy pattern.
var proxied = $.fn.draggable;
$.fn.draggable = (function (method){
if (method === "refreshContainment") {
this.each(function (){
var inst = $(this).data("draggable");
// Check if the draggable is already being dragged.
var isDragging = inst.helper && inst.helper.is(".ui-draggable-dragging");
// We are going to use the existing _mouseStart method to take care of
// refreshing the containtment but, since we don't actually intend to
// emulate a true _mouseStart, we have to avoid any extraneous
// operations like the drag/drop manager and event triggering.
// So we save the original member values and replace them with dummies.
var ddmanager = $.ui.ddmanager;
$.ui.ddmanager = null;
var trigger = inst._trigger;
inst._trigger = function () { return true; }
var mousePosition = $window.data("refreshContainment").mousePosition;
var fakeEvent = {
pageX: mousePosition.pageX, pageY: mousePosition.pageY
};
inst._mouseStart(fakeEvent);
// Return those extraneous members back to the original values.
inst._trigger = trigger;
$.ui.ddmanager = ddmanager;
// Clear the drag, unless it was already being dragged.
if (!isDragging) {
inst._clear();
}
});
return this;
}
else {
// Delegate all other calls to the actual draggable implemenation.
return proxied.apply(this, arguments);
}
});
})(jQuery);
<!DOCTYPE html>
<html>
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
#container { width: 20em; height: 20em; border: 0.5em solid black; }
.draggable { width: 5em; height: 5em; border: 0.2em solid black; position: absolute; }
#one { background-color: #F55; }
#two { background-color: #5F5; }
</style>
</head>
<body>
<div id="container">
<div class="draggable" id="one">drag me</div>
<div class="draggable" id="two">drag me</div>
</div>
</body>
</html>
var draggables = $('.draggable');
draggables.draggable({containment: 'parent', stack: draggables});
var resizeDraggables = function (){
draggables.
each(function (){
var size = 5 + Math.random() * 5;
size = size.toString() + "em";
$(this).css({width: size, height: size});
}).
draggable("refreshContainment");
};
resizeDraggables();
setInterval(resizeDraggables, 2000);
答案 1 :(得分:3)
这有用吗?
$("#yourcontainment").bind("resizestop", function () {
$(".yourdraggables").draggable("option", "containment", $("#yourcontainment"));
});
如果你不使用jQuery UI的可调整大小,你必须触发“resizestop”事件。
答案 2 :(得分:0)
因为您正在修改[包含]元素大小,所以必须为结果实现自己的处理程序。 jQuery知道在拖动过程中该做什么,但在调整大小期间有许多可能的行为:
可以想象出一系列针对不同UI约束的虚拟场景。
只需为包含的类的所有对象创建一个PostionValidator()方法,并在调用modify方法后执行它。