javascript-jQuery UI:拖动多个对象
作者:互联网
我的场景:带有某些对象(div)的容器(div).可以在容器内部移动对象(将选项包含设置为父对象).
现在,我需要一次移动多个对象.为此,我发现了this有用的插件.不幸的是,此插件无法处理属性包含,如报告的here所示.
My test on JSFiddle,禁用此功能
$(".obj").on("drag", function(ev, ui)
要激活多重拖动,请单击对象.我能够阻止拖动事件.
我的测试问题:
那时我不知道如何重新激活拖动.
注意
我大概应该知道拖动的方向(带有开始-停止事件).但是在这一点上,我无法停止拖累.
我的解决方案
但是K Scandrett解决方案也非常好.在我的特殊情况下很难应用,在示例中已对此进行了简化.
始终使用this插件启用多重拖动.每次我选择多个对象并将其拖动时,在dragstart事件中都会执行此操作(根据所选对象的位置更改对象的属性包含):
//1024 * 648 is the width of the container
$(obj).unbind("dragstart").bind("dragstart" , function(ev, ui){
var dimObjFirst = {
x : parseInt($(this).css("left")),
y : parseInt($(this).css("top"))
};
if($("blablabla > div.ui-selected").length > 1){
var minLeft = 1024,maxRight = 0,minTop = 648,maxDown = 0;
$("blablabla > div.ui-selected").each(function(){
var elem = $(this);
var dim = {
w : parseInt(elem.css("width")),
h : parseInt(elem.css("height")),
l : parseInt(elem.css("left")),
t : parseInt(elem.css("top")),
};
if(dim.l < minLeft) minLeft = dim.l;
if(dim.l + dim.w > maxRight) maxRight = dim.l + dim.w;
if(dim.t < minTop) minTop = dim.t;
if(dim.t + dim.h > maxDown) maxDown = dim.t + dim.h;
});
var offsetContainer = $(".container").offset();
$(this).draggable( "option" , "containment" , [
(dimObjFirst.x - minLeft) + parseInt(offsetContainer.left),
(dimObjFirst.y - minTop) + parseInt(offsetContainer.top),
(dimObjFirst.x + (1024 - maxRight)) + parseInt(offsetContainer.left),
(dimObjFirst.y) + (648 - maxDown) + parseInt(offsetContainer.top)
]);
}
});
$(obj).unbind("dragstop").on("dragstop", function(ev, ui) {
if($("blablabla > div.ui-selected").length > 1) {
$("blablabla > div.ui-selected").each(function(){
$(this).draggable( "option" , "containment" , "parent" );
});
}
});
并添加以下代码行this._setContainment();在jQuery UI插件的_mouseDrag函数的开头.
解决方法:
看起来像是一个有趣的项目,所以…
我用一个边界框实现了它(类似于Twisty的注释).
我认为这样做的好处是它将所有多个选定对象限制在容器的边界.
我已为边框上色,以便您可以直观地看到其工作方式.当然,您可能会在实践中保持透明.
代码注释是内联的,但是很高兴回答代码中的任何问题.
没有使用插件(只是jQuery和jQueryUI).
var disableclick = false;
var boundingBoxTop, boundingBoxBottom, boundingBoxLeft, boundingBoxRight;
var $container = $("#container");
var containerHeight = $container.height();
var containerWidth = $container.width();
var containerTop = $container.offset().top;
var containerLeft = $container.offset().left;
// add the bounding box to the container and make it draggable
var $boundingBox = $("<div id='boundingBox' style='position:absolute;background-color:#fcf5d4'>").prependTo($container);
$boundingBox.draggable({
grid: [10, 10],
containment: "parent",
stop: function( event, ui ) {
disableclick = true; // don't want to toggle selection when dragging
setTimeout(function(e){
disableclick = false;
},200);
},
});
$(".obj").click(function(e) {
if (!disableclick) {
var $objClicked = $(this);
$objClicked.toggleClass("ui-selected");
var $selectedItems = $("#container .ui-selected");
// move any items in bounding box back into container before we re-process them
$boundingBox.find('*').each(function() {
var $this = $(this);
if ($this.parent().is($boundingBox)) {
// adjust its positioning to be relative to the container
$this.css("top", ($this.offset().top - containerTop) + "px");
$this.css("left", ($this.offset().left - containerLeft) + "px");
$container.append($this); // return it to the container
}
});
// reversing co-ords to what might be expected here so that we can scale them back to what they need to be for a bounding box
boundingBoxTop = containerHeight;
boundingBoxBottom = 0;
boundingBoxLeft = containerWidth;
boundingBoxRight = 0;
// find the bounds of the smallest rectangle that will cover all the currently selected objects
$selectedItems.each(function() {
var $this = $(this);
var top = $this.offset().top - containerTop;
var bottom = $this.offset().top - containerTop + $this.height();
var left = $this.offset().left - containerLeft;
var right = $this.offset().left - containerLeft + $this.width();
boundingBoxTop = (top < boundingBoxTop) ? top : boundingBoxTop;
boundingBoxBottom = (bottom > boundingBoxBottom) ? bottom : boundingBoxBottom;
boundingBoxLeft = (left < boundingBoxLeft) ? left : boundingBoxLeft;
boundingBoxRight = (right > boundingBoxRight) ? right : boundingBoxRight;
});
// get the height and width of bounding box
var boundingBoxHeight = boundingBoxBottom -= boundingBoxTop;
var boundingBoxWidth = boundingBoxRight -= boundingBoxLeft;
if (boundingBoxBottom > 0) // will be negative when nothing is selected
{
// update the bounding box with its new position and size
$boundingBox.css("top", boundingBoxTop + "px");
$boundingBox.css("left", boundingBoxLeft + "px");
$boundingBox.css("width", boundingBoxWidth + "px");
$boundingBox.css("height", boundingBoxHeight + "px");
// add each selected item to the bounding box so we can drag the box with them in it
$selectedItems.each(function() {
var $this = $(this);
// correct the item's position to be relative to the bounding box
$this.css("top", ($this.offset().top - containerTop - boundingBoxTop) + "px");
$this.css("left", ($this.offset().left - containerLeft - boundingBoxLeft) + "px");
$boundingBox.append($this); // add item to bounding box
});
}
}
});
#container {
position: absolute;
width: 400px;
height: 150px;
background: #eee;
}
.obj {
position: absolute;
background: #ccc;
}
.ui-selected {
background: #1C90F3;
}
#obj1 {
width: 20px;
height: 20px;
left: 20px;
top: 20px;
}
#obj2 {
width: 20px;
height: 20px;
left: 100px;
top: 20px;
}
#obj3 {
width: 20px;
height: 20px;
left: 20px;
top: 100px;
}
#obj4 {
width: 20px;
height: 20px;
left: 100px;
top: 100px;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/jquery-3.2.1.min.js" />
<div style="margin-bottom:10px">
Click boxes to select/deselect multiple items.<br/>Drag to move selection.
</div>
<div id="container">
<div class="obj" id="obj1"></div>
<div class="obj" id="obj2"></div>
<div class="obj" id="obj3"></div>
<div class="obj" id="obj4"></div>
</div>
标签:jquery-ui-draggable,jquery-ui,javascript 来源: https://codeday.me/bug/20191025/1931827.html