一个拖拽组件(二)

改写了一下,可支持同一页面内同时存在多个拖动对象,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);
    };
};
示例下载:drag_code.rar
posted @ 2011-07-28 13:46  ihada  阅读(326)  评论(2编辑  收藏  举报