|
Code
//拖放程式
var Drag = Class.create();
Drag.prototype = {
//拖放對象
initialize: function(drag, options) {
this.Drag = $(drag);//拖放對象
this._x = this._y = 0;//記錄滑鼠相對拖放對象的位置
this._marginLeft = this._marginTop = 0;//記錄margin
//事件對象(用於綁定移除事件)
this._fM = BindAsEventListener(this, this.Move);
this._fS = Bind(this, this.Stop);
this.SetOptions(options);
this.Limit = !!this.options.Limit;
this.mxLeft = parseInt(this.options.mxLeft);
this.mxRight = parseInt(this.options.mxRight);
this.mxTop = parseInt(this.options.mxTop);
this.mxBottom = parseInt(this.options.mxBottom);
this.LockX = !!this.options.LockX;
this.LockY = !!this.options.LockY;
this.Lock = !!this.options.Lock;
this.onStart = this.options.onStart;
this.onMove = this.options.onMove;
this.onStop = this.options.onStop;
this._Handle = $(this.options.Handle) || this.Drag;
this._mxContainer = $(this.options.mxContainer) || null;
this.Drag.style.position = "absolute";
//透明
if(isIE && !!this.options.Transparent){
//填充拖放對象
with(this._Handle.appendChild(document.createElement("div")).style){
width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)"; fontSize = 0;
}
}
//修正範圍
this.Repair();
addEventHandler(this._Handle, "mousedown", BindAsEventListener(this, this.Start));
},
//設定預設屬性
SetOptions: function(options) {
this.options = {//預設值
Handle: "",//設定觸發對象(不設定則使用拖放對象)
Limit: false,//是否設定範圍限制(為true時下面參數有用,可以是負數)
mxLeft: 0,//左邊限制
mxRight: 9999,//右邊限制
mxTop: 0,//上邊限制
mxBottom: 9999,//下邊限制
mxContainer: "",//指定限制在容器內
LockX: false,//是否鎖定水平方向拖放
LockY: false,//是否鎖定垂直方向拖放
Lock: false,//是否鎖定
Transparent: false,//是否透明
onStart: function(){},//開始移動時執行
onMove: function(){},//移動時執行
onStop: function(){}//結束移動時執行
};
Extend(this.options, options || {});
},
//準備拖動
Start: function(oEvent) {
if(this.Lock){ return; }
this.Repair();
//記錄滑鼠相對拖放對象的位置
this._x = oEvent.clientX - this.Drag.offsetLeft;
this._y = oEvent.clientY - this.Drag.offsetTop;
//記錄margin
this._marginLeft = parseInt(CurrentStyle(this.Drag).marginLeft) || 0;
this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0;
//mousemove時移動 mouseup時停止
addEventHandler(document, "mousemove", this._fM);
addEventHandler(document, "mouseup", this._fS);
if(isIE){
//焦點丟失
addEventHandler(this._Handle, "losecapture", this._fS);
//設定滑鼠捕獲
this._Handle.setCapture();
}else{
//焦點丟失
addEventHandler(window, "blur", this._fS);
//阻止預設動作
oEvent.preventDefault();
};
//附加程式
this.onStart();
},
//修正範圍
Repair: function() {
if(this.Limit){
//修正錯誤範圍參數
this.mxRight = Math.max(this.mxRight, this.mxLeft + this.Drag.offsetWidth);
this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.Drag.offsetHeight);
//如果有容器必須設定position為relative來相對定位,並在擷取offset之前設定
!this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative");
}
},
//拖動
Move: function(oEvent) {
//判斷是否鎖定
if(this.Lock){ this.Stop(); return; };
//清除選擇
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//設定移動參數
var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY - this._y;
//設定範圍限制
if(this.Limit){
//設定範圍參數
var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
//如果設定了容器,再修正範圍參數
if(!!this._mxContainer){
mxLeft = Math.max(mxLeft, 0);
mxTop = Math.max(mxTop, 0);
mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
};
//修正移動參數
iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft);
iTop = Math.max(Math.min(iTop, mxBottom - this.Drag.offsetHeight), mxTop);
}
//設定位置,並修正margin
if(!this.LockX){ this.Drag.style.left = iLeft - this._marginLeft + "px"; }
if(!this.LockY){ this.Drag.style.top = iTop - this._marginTop + "px"; }
//附加程式
this.onMove();
},
//停止拖動
Stop: function() {
//移除事件
removeEventHandler(document, "mousemove", this._fM);
removeEventHandler(document, "mouseup", this._fS);
if(isIE){
removeEventHandler(this._Handle, "losecapture", this._fS);
this._Handle.releaseCapture();
}else{
removeEventHandler(window, "blur", this._fS);
};
//附加程式
this.onStop();
}
}; |