遗憾的是,我最终也没能实现这个功能,我想,这可能与draggable元素的snap的判定有关,或许修改jquery-ui的源文件能解决这个问题,很可惜,我没有这样的能力。
我换用了另一种方式来实现这个功能,他看起来有着与snap一样的外表,或许能够一定程度上解决和我遭遇了同样问题的人:
这分为两部分,我将draggable元素命名为“#ball”,snap元素命名为“#block”
在#block上,我进行了这样的设置:
$("#block").droppable({
tolerance: "pointer",
accept:"#ball",
//球的圆心在鼠标的位置,所以我使用了pointer,当鼠标进入block时,球的圆心也进入了block
over:function(event,ui){
event.stopPropagation()
//通过修改snapping变量令ball的drag事件停止
snapping = true
//获取block的中心,这里的block是一个圆形
var radius = $(this).width()/2
var x = $(this).offset().left + radius
var y = $(this).offset().top + radius
//将ball的圆心移动到这里来
$(ui.draggable).offset({
left: x - ball的半径,
top: y - ball的半径
})
},
drop:function(event,ui){
console.log("球放进了篮子里")
},
//当鼠标移出block时
out:function(event,ui){
event.stopPropagation()
//令drag事件重启
snapping = false
//将ball移动到鼠标的位置来
$(ui.draggable).offset({
left: event.clientX,
top: event.clientY
})
}
})
另一边,我同样对#ball的draggable进行了设置:
$("#ball").draggable({
//我的block是一个在ball开始移动后才创建的对象,也正是因此snap无法起效,这里需要给ball设置refreshPositions:true,才能检测到新创建的block对象
refreshPositions:true,
//以snapping变量限制drag行动
drag: function(event,ui) {
if(snapping != false){
draggingBall(this)
}
else{
//在此时,ball的拖拽事件将不会发生
return 0;
}
},
stop: function(){
console.log("已经结束了!")
}
})
需要提及的是,在我的程序中,ball的移动是借由helper产生,而非ball本身进行的移动,因此,这个代码可能不会在任何情况有效,但我希望它能够作为一种参考