Javascript 带冲突检测的jQuery拖动

Javascript 带冲突检测的jQuery拖动,javascript,jquery,collision-detection,jquery-ui-draggable,Javascript,Jquery,Collision Detection,Jquery Ui Draggable,我有以下HTML: <div class="list" id="list"> <div class="item" id="i1">Item 1</div> <div class="item" id="i2">Item 2</div> <div class="item" id="i3">Item 3</div> </div> <div class="timeline" id

我有以下HTML:

<div class="list" id="list">
    <div class="item" id="i1">Item 1</div>
    <div class="item" id="i2">Item 2</div>
    <div class="item" id="i3">Item 3</div>
</div>
<div class="timeline" id="timeline">
</div>
我的问题是jQueryUI可拖动冲突插件仅在拖动原始Div本身而不是拖动辅助对象时才起作用。我需要助手,以便实现#2(添加一个项目的多个副本)。但是我需要一些类似于碰撞插件的东西,这样我就可以实现#3(项目不重叠)


有人知道这个问题的解决办法吗?是否有其他插件可以在可拖动对象的辅助对象上执行碰撞检测?有没有其他方法可以尝试实现我想要实现的目标?

下面是我为这个问题编写的一个示例,展示了一个带有冲突检测的简单拖放插件。 它允许您将项目放置到时间线上,只要项目存在的空间没有重叠

这绝不是一个成品,但希望它能说明这样的代码编写起来并不复杂,试图将大量相互冲突的插件拼凑在一起并不总是最好的选择。有时候最好从头开始。这很有趣,也是一种很好的学习方式

/*------------文件准备就绪----------*/
$(文档).ready(函数(){
$(“#时间线”)。时间线({
项目:“.项目”
});
});
/*----------时间线插件----------*/
$.fn.timeline=功能(选项){
var默认值={
项目:“部门”
}
var options=$.extend(默认值,选项)
返回此值。每个(函数(){
//-----设置-----//
//定义我们以后需要的所有变量
var el=$(本);
var items=$(options.items);
var mousedown=false;
var=false;
var-activeItem=false;
var placedItems=新数组();
//使所有内容都不可选择,这样就不会影响拖动
$(“html”).find(“*”).css({
“用户选择”:“无”,
“-moz用户选择”:“无”,
“-webkit用户选择”:“无”,
“-ms用户选择”:“无”,
“-o-user-select”:“无”,
}).attr(“不可选择”、“真”).unbind(“onselectstart”);
//-----事件-----//
//当鼠标落在文档的任何位置时记录
$(文档).mousedown(函数(){
mousedown=true;
});
//当鼠标被释放时
$(文档).mouseup(函数(e){
//如果正在拖动项目,请尝试放置该项目
如果(鼠标向下拖动(&D){
项目(e);
}
//记录拖动已停止
mousedown=false;
拖动=假;
});
//将鼠标按在项目上时记录
items.mousedown(函数(){
拖动=真;
//克隆活动项并将其隐藏以备拖动
activeItem=$(this.clone().appendTo(“body”).hide();
});
//当鼠标移动到文档上时
$(文档).mousemove(函数(e){
//如果将鼠标按在项目上,请尝试拖动
如果(鼠标向下拖动(&D){
德拉吉特姆(e);
}
});
//-----功能-----//
//在屏幕上拖动项目
函数dragItem(e){
//如果未完成任何活动项,则执行owt
如果(!activeItem){
返回false;
}
//找出拖曳锚的位置
var x=e.pageX-(activeItem.height()/2);
var y=e.pageY-(activeItem.width()/2);
//保存原始位置,以防无法放置项目
如果(!activeItem.origPos){
activeItem.origPos={
x:x,
y:y
}
}
//拖动项目
activeItem.css({
“位置”:“绝对”,
“顶部”:y,
“左”:x,
“z索引”:“999”,
“不透明度”:0.6,
“显示”:“块”
});
}
//尝试放置项目
功能项目(e){
//如果没有活动项,请不要执行owt
如果(!activeItem){
返回false;
}
//定义以后需要的som变量
var onTargetY=假;
var onTargetX=假;
var=false;
var冲突=假;
//检查项目是否在时间线范围内被释放
如果(e.pageY>el.position().top和&e.pageYel.position().left&&e.pageXmaxRight){
x=maxRight;
}
//循环时间线上已有的项目并检查冲突
$.each(placedItems,function(i,item){
var itemMin=item.position().left;
var itemMax=item.position().left+item.width();
如果(x+activeItem.width()>itemMin&&x$('#list .item').draggable({
    helper: 'clone',
    revert: 'invalid',
    //the following are for the jquery-ui-dragggable-collision plugin
    obstacle: '#timeline .item',
    preventCollision: true
});
$('#timeline').droppable({
    accept: '.item'
});
$(function(){
    var draggableSelector = ".list .item:not(.dropped)";
    var init = function() {  
        $(draggableSelector).each(function(i){
            $(this)
                .draggable({
                    //helper: 'clone',
                    revert: 'invalid',
                    start: function(event,ui) {
                        var $clone = ui.helper.clone();
                        $clone
                            .removeClass("ui-draggable ui-draggable-dragging")
                            .insertAfter(ui.helper)
                        ;
                        $(this).data("clone",$clone);
                    },
                    stop: function(event,ui) {
                        if( $(".ui-draggable-dragging.dropped").length == 0) {
                            $(this).data("clone").remove();
                        };
                    },
                    //the following are for the jquery-ui-draggable-collision plugin
                    refreshPositions: true,
                    obstacle: '.item.dropped',
                    preventCollision: true,
                })
                .css("left", ( ($(this).width() + 5) * i) + "px")
            ;
        });

        $('.timeline').droppable({
            accept: '.item'
            ,drop: function(event,ui) {
                ui.draggable
                    .addClass("dropped")
                ;
                setTimeout(reinit, 500);
            }
        });                
    };

    var reinit = function() {
        $(".list .item.ui-draggable").draggable("destroy");
        init();
    }

    init();
});