zoukankan      html  css  js  c++  java
  • 一个拖拽组件(二)

    改写了一下,可支持同一页面内同时存在多个拖动对象,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
  • 相关阅读:
    动态代理:JDK动态代理和CGLIB代理的区别
    spring启动component-scan类扫描加载,以及@Resource,postConstruct等等注解的解析生效源码
    spring启动component-scan类扫描加载过程---源码分析
    spring源码分析之spring-core asm概述
    Spring组件扫描 <context:component-scan/>
    【OSGI】1.初识OSGI-到底什么是OSGI
    superrvisor application config ini
    doris 0.9.0版本docker镜像制作与使用
    Docker系列09:搭建Harbor本地镜像仓库
    Docker系列08:容器监控
  • 原文地址:https://www.cnblogs.com/ihada/p/drag2.html
Copyright © 2011-2022 走看看