我整理了一个定义Draggable 对象的简单工作示例。您指定拖动项目(您要移动的元素)以及拖动边界(您要在其中移动项目的空间或元素)。如果您想将可拖动项目限制在页面上的某个空间(例如容器),或定义作为数学基础的相对坐标系,边界 的概念很重要。
我的解决方案不是最快的,但它展示了这个概念:
$(function() {
window.mousedown = 0;
$(window).on('mousedown mouseup', function(e) {
if(e.type == 'mousedown') { this.mousedown++; }
else { this.mousedown--; }
});
var Draggable = function(dragItem, dragBoundary) {
this.item = $(dragItem).css('position', 'absolute');
this.item.on('mousemove', $.proxy(this.handleDragEvent, this));
this.boundary = $(dragBoundary).css('position', 'relative');
};
Draggable.prototype.handleDragEvent = function(e) {
if(window.mousedown) {
var mousePosition = this.mapToBoundary([e.clientX, e.clientY]);
var mouseX = mousePosition[0],
mouseY = mousePosition[1];
if(typeof this.prevMouseX == "undefined") this.prevMouseX = mouseX;
if(typeof this.prevMouseY == "undefined") this.prevMouseY = mouseY;
this.itemX = this.item.offset().left - this.boundary.offset().left;
this.itemY = this.item.offset().top - this.boundary.offset().top;
var deltaX = mouseX - this.prevMouseX,
deltaY = mouseY - this.prevMouseY;
this.item.css({
'left': this.itemX + deltaX,
'top': this.itemY + deltaY
});
this.prevMouseX = mouseX;
this.prevMouseY = mouseY;
}
};
Draggable.prototype.mapToBoundary = function(coord) {
var x = coord[0] - this.boundary.offset().left;
var y = coord[1] - this.boundary.offset().top;
return [x,y];
};
var draggable = new Draggable($('.draggable'), $('.container'));
});
请注意,我们在全局上维护了一个 mousedown 值,允许我们确定何时适合在我们的元素周围拖动(我们只为拖动项添加一个 mousemove 监听器本身)。我还在边界div 上方添加了一个分隔符div,以演示如何在页面周围的任何位置移动边界并且坐标系仍然准确。实际上限制可拖动项目在其指定边界内的代码可以使用简单的数学来编写。
这里是小提琴:http://jsfiddle.net/bTh9s/3/
编辑:
这里是一些限制可拖动项目在其容器内的代码的开始。
Draggable.prototype.restrictItemToBoundary = function() {
var position = this.item.position();
position.right = position.left + this.item.outerWidth();
position.bottom = position.top + this.item.outerHeight();
if(position.left <= 0) {
this.item.css('left', 1);
} else if(position.right >= this.boundary.outerWidth()) {
this.item.css('left', this.boundary.outerWidth() - this.item.outerWidth());
}
if(position.top <= 0) {
this.item.css('top', 1);
} else if(position.bottom >= this.boundary.outerHeight()) {
this.item.css('top', this.boundary.outerHeight() - this.item.outerHeight());
}
};
应该在您更新拖动项的 CSS 定位后,在 Draggable.handleDragEvent 内部调用此方法。这个解决方案似乎有问题,但这是一个开始。