一个拖拽组件

/*
*使用方法:
*    var d = new Drag({id:'dragPannel',maxLeft:500,maxTop:200});
*    d.ready();
*请注意:
*    拖动对象的left和top样式必须写在其style属性里边
*
*/

//矫正调用者。将 fn 作为 newObj 的方法调用
function repairCaller(newObj, fn){
    return function(){
        return fn.apply(newObj, arguments);
    }
}

function Drag( config ){
    this.moveTarget = T.dom.get( config.id );
    this.startLeft = parseInt(this.moveTarget.style.left);       //每次拖动开始时被拖动对象的 left,top
    this.startTop = parseInt(this.moveTarget.style.top);
    this.startClientX = this.startLeft;    //保存拖动开始时事件的 clientX, clientY
    this.startClientY = this.startTop;
    this.MAX_LEFT = config.maxLeft||document.documentElement.clientWidth - this.moveTarget.offsetWidth;     //元素可以移动的最大范围
    this.MAX_TOP = config.maxTop||document.documentElement.clientHeight - this.moveTarget.offsetHeight;
    this.lock = true;
}


Drag.prototype.ready = function(){
    //绑定事件
    T.bind(document, "mousedown", repairCaller(this,this.down));
    T.bind(document, "mousemove", repairCaller(this,this.move));
    T.bind(document, "mouseup", repairCaller(this,this.stop));
}

Drag.prototype.down = function(){
    //取得事件对象
    var event = T.event.getEvent(arguments[0]),
        target = T.event.getTarget(event);
        
    if (target == this.moveTarget){        
        this.lock = false;
        
        //在事件开始时保存各种坐标位置
        this.startLeft = parseInt(this.moveTarget.style.left);
        this.startTop = parseInt(this.moveTarget.style.top);
        this.startClientX = event.clientX;
        this.startClientY = event.clientY;
    }
};

Drag.prototype.move = function(){
    if(!this.lock ){
        //取得事件对象
        var event = T.event.getEvent(arguments[0]),
            target = T.event.getTarget(event);
        
        if(target == this.moveTarget){
            //如有选择内容,清除之
            //window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
            
            //凑数拖动范围有没超过最大限制
            var realLeft = this.startLeft + event.clientX - this.startClientX,  //实际的移动范围
                realTop = this.startTop + event.clientY - this.startClientY,
                rightLeft , rightTop;  //正确的 left, top 取值
                
            rightLeft = realLeft > this.MAX_LEFT ? this.MAX_LEFT : ( realLeft > 0 ? realLeft : 0 );
            rightTop = realTop > this.MAX_TOP ? this.MAX_TOP : ( realTop > 0 ? realTop : 0 );
            
            this.moveTarget.style.left = rightLeft + "px";
            this.moveTarget.style.top = rightTop + "px";
        }
        else{
            this.lock = true;
        }
    }
};

Drag.prototype.stop = function(){
    this.lock = true
};


 后记:

        在写的过程中非常需要注意的几点是:

     1、拖动层的 position、left 和 top 必须写在 style 里

     2、移动过程中设置 left 和 top 要带单位,否则不起作用

     3、多级 div 嵌套时需要给父 div 加 over-flow:hidden 样式

 完毕!

原文地址:https://www.cnblogs.com/ihada/p/drag.html