一个拖拽组件(二)
改写了一下,可支持同一页面内同时存在多个拖动对象,FF下面有点慢,估计是没取消冒泡造成的,我自己尝试了下,没有进展,希望等到高手指教!
/*
*使用方法:
* var d = new Drag({id:'xxx',range:{maxLeft:100,minLeft:100,maxTop:100,minTop:100}});
* d.ready();
*请注意:
* 拖动对象的left和top样式必须写在其style属性里边
*
*/
//矫正调用者。将 fn 作为 newObj 的方法调用
function repairCaller(newObj, fn){
return function(){
return fn.apply(newObj, arguments);
}
}
//保存所有拖动对象中最大的 zIndex 属性值
var maxZIndex = 0;
function Drag( config ){
this.target = T.dom.get( config.id );
//保存每次拖动开始时被拖动对象的 left,top,和拖动结束时根据移动计算出的理论 realLeft, realTop 值及结合范围修正后的 rightLeft, rightTop 值
this.targetCoord = {
start:{
left:parseInt(this.target.style.left),
top:parseInt(this.target.style.top)
},
real:{
left: parseInt(this.target.style.left),
top: parseInt(this.target.style.top)
},
right:{
left: parseInt(this.target.style.left),
top: parseInt(this.target.style.top)
}
};
//保存拖动开始、结束时事件的 clientX, clientY,初始化时设置为目标的 left, top,然后在每次拖动开始和结束时进行设置
this.eventCoord = {
start:{
X: this.targetCoord.start.left,
Y: this.targetCoord.start.top
}
};
//元素可以移动的范围
this.range = {
minLeft:config.range.minLeft || 0,
maxLeft:(config.range.maxLeft || document.documentElement.clientWidth) - this.target.offsetWidth,
minTop:config.range.minTop || 0,
maxTop:(config.range.maxTop || document.documentElement.clientHeight) - this.target.offsetHeight,
};
//初始化时锁定拖动对象
this.lock = true;
}
Drag.prototype.start = function(){
//解锁当前拖动对象
this.lock = false;
//在每次开始移动时将其 z-index 属性设置为:所有拖动对象中的最大值 + 1
if(this.target.style.zIndex < maxZIndex){
this.target.style.zIndex = ++maxZIndex;
};
//绑定事件
T.bind(document,'mousemove',repairCaller(this,this.move));
T.bind(document,'mouseup',repairCaller(this,this.stop));
//取得事件对象
var event = T.event.getEvent(arguments[0]);
//在事件开始时保存各种坐标位置
this.targetCoord.start.left = parseInt(this.target.style.left);
this.targetCoord.start.top = parseInt(this.target.style.top);
this.eventCoord.start.X = event.clientX;
this.eventCoord.start.Y = event.clientY;
};
Drag.prototype.move = function(){
if(!this.lock){
//取得事件对象
var event = T.event.getEvent(arguments[0]),
target = T.event.getTarget(event);
// 查看事件的当前目标对象
// 如果是 this.target ,即表明鼠标仍落在 this.target 上,移动有效;否则说明鼠标移出了 this.target ,锁定 this.target
if (target == this.target){
//如有选择内容,进行清除
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
/*
* 修正拖动范围,查看拖动有没超过限制
*/
//获得实际的 left,top
this.targetCoord.real.left = this.targetCoord.start.left + event.clientX - this.eventCoord.start.X;
this.targetCoord.real.top = this.targetCoord.start.top + event.clientY - this.eventCoord.start.Y;
//根据获得实际的 left,top 计算出正确的 left, top
this.targetCoord.right.left = this.targetCoord.real.left > this.range.maxLeft ? this.range.maxLeft :
( this.targetCoord.real.left > this.range.minLeft ? this.targetCoord.real.left : this.range.minLeft );
this.targetCoord.right.top = this.targetCoord.real.top > this.range.maxTop ? this.range.maxTop :
( this.targetCoord.real.top > this.range.minTop ? this.targetCoord.real.top : this.range.minTop );
this.target.style.left = this.targetCoord.right.left + 'px';
this.target.style.top = this.targetCoord.right.top + 'px';
}
else{
this.lock = true;
}
}
};
Drag.prototype.stop = function(){
if(!this.lock){
this.lock = true;
}
//如有选择内容,进行清除
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//移除事件
T.unbind(document,'mousemove',repairCaller(this,this.move));
T.unbind(document,'mouseup',repairCaller(this,this.stop));
};
Drag.prototype.ready = function(){
//绑定事件
T.bind(this.target,'mousedown',repairCaller(this,this.start));
//初始化时获得所有拖动对象中最大的 zIndex 属性值
if(this.target.style.zIndex > maxZIndex){
maxZIndex = parseInt(this.target.style.zIndex,10);
};
};
*使用方法:
* var d = new Drag({id:'xxx',range:{maxLeft:100,minLeft:100,maxTop:100,minTop:100}});
* d.ready();
*请注意:
* 拖动对象的left和top样式必须写在其style属性里边
*
*/
//矫正调用者。将 fn 作为 newObj 的方法调用
function repairCaller(newObj, fn){
return function(){
return fn.apply(newObj, arguments);
}
}
//保存所有拖动对象中最大的 zIndex 属性值
var maxZIndex = 0;
function Drag( config ){
this.target = T.dom.get( config.id );
//保存每次拖动开始时被拖动对象的 left,top,和拖动结束时根据移动计算出的理论 realLeft, realTop 值及结合范围修正后的 rightLeft, rightTop 值
this.targetCoord = {
start:{
left:parseInt(this.target.style.left),
top:parseInt(this.target.style.top)
},
real:{
left: parseInt(this.target.style.left),
top: parseInt(this.target.style.top)
},
right:{
left: parseInt(this.target.style.left),
top: parseInt(this.target.style.top)
}
};
//保存拖动开始、结束时事件的 clientX, clientY,初始化时设置为目标的 left, top,然后在每次拖动开始和结束时进行设置
this.eventCoord = {
start:{
X: this.targetCoord.start.left,
Y: this.targetCoord.start.top
}
};
//元素可以移动的范围
this.range = {
minLeft:config.range.minLeft || 0,
maxLeft:(config.range.maxLeft || document.documentElement.clientWidth) - this.target.offsetWidth,
minTop:config.range.minTop || 0,
maxTop:(config.range.maxTop || document.documentElement.clientHeight) - this.target.offsetHeight,
};
//初始化时锁定拖动对象
this.lock = true;
}
Drag.prototype.start = function(){
//解锁当前拖动对象
this.lock = false;
//在每次开始移动时将其 z-index 属性设置为:所有拖动对象中的最大值 + 1
if(this.target.style.zIndex < maxZIndex){
this.target.style.zIndex = ++maxZIndex;
};
//绑定事件
T.bind(document,'mousemove',repairCaller(this,this.move));
T.bind(document,'mouseup',repairCaller(this,this.stop));
//取得事件对象
var event = T.event.getEvent(arguments[0]);
//在事件开始时保存各种坐标位置
this.targetCoord.start.left = parseInt(this.target.style.left);
this.targetCoord.start.top = parseInt(this.target.style.top);
this.eventCoord.start.X = event.clientX;
this.eventCoord.start.Y = event.clientY;
};
Drag.prototype.move = function(){
if(!this.lock){
//取得事件对象
var event = T.event.getEvent(arguments[0]),
target = T.event.getTarget(event);
// 查看事件的当前目标对象
// 如果是 this.target ,即表明鼠标仍落在 this.target 上,移动有效;否则说明鼠标移出了 this.target ,锁定 this.target
if (target == this.target){
//如有选择内容,进行清除
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
/*
* 修正拖动范围,查看拖动有没超过限制
*/
//获得实际的 left,top
this.targetCoord.real.left = this.targetCoord.start.left + event.clientX - this.eventCoord.start.X;
this.targetCoord.real.top = this.targetCoord.start.top + event.clientY - this.eventCoord.start.Y;
//根据获得实际的 left,top 计算出正确的 left, top
this.targetCoord.right.left = this.targetCoord.real.left > this.range.maxLeft ? this.range.maxLeft :
( this.targetCoord.real.left > this.range.minLeft ? this.targetCoord.real.left : this.range.minLeft );
this.targetCoord.right.top = this.targetCoord.real.top > this.range.maxTop ? this.range.maxTop :
( this.targetCoord.real.top > this.range.minTop ? this.targetCoord.real.top : this.range.minTop );
this.target.style.left = this.targetCoord.right.left + 'px';
this.target.style.top = this.targetCoord.right.top + 'px';
}
else{
this.lock = true;
}
}
};
Drag.prototype.stop = function(){
if(!this.lock){
this.lock = true;
}
//如有选择内容,进行清除
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//移除事件
T.unbind(document,'mousemove',repairCaller(this,this.move));
T.unbind(document,'mouseup',repairCaller(this,this.stop));
};
Drag.prototype.ready = function(){
//绑定事件
T.bind(this.target,'mousedown',repairCaller(this,this.start));
//初始化时获得所有拖动对象中最大的 zIndex 属性值
if(this.target.style.zIndex > maxZIndex){
maxZIndex = parseInt(this.target.style.zIndex,10);
};
};