面向对象的拖拽

作者: icessun | 来源:发表于2017-08-10 21:41 被阅读8次

    面向对象中,尽量避免函数嵌套;公共用的东西放在构造函数(constructor)里面,初始位置是公共的东西,大家都能用;尽量保证所有的this指向实例;

    Drag.js 拖拽

    拖拽三个函数,按下down,移动move,抬起up

    class Drag{
        // 构造函数 实例可以调用 私有属性和方法 
        constructor(opt){ 
         // 保证opt存在,不出错
         opt=opt||{};
         if(!opt.el) return;
       
           this.el=opt.el; // 获取这个元素
            this.l=null;
            this.t=null;
            this.x=null;
            this.y=null;
        
            this.DOWN=processThis(this.down,this);
            this.MOVE=this.UP=null;
            this.xtimer=this.ytimer=null;
            on(this.el,'mousedown',this.DOWN);
          
         }
    
        down(e){
           // 按下的时候保存元素的初始位置  事件.clientX/clientY:鼠标落脚点距离浏览器边框的距离;offsetX/offsetY:鼠标落脚点距离物体自身边距的距离,也就是鼠标落脚点到物体的距离;[元素.offsetLeft/offsetTop]:表示元素自身的宽度和高度,元素才有offsetLeft/offsetTop
           this.x=e.clientX; // 鼠标落脚点距离浏览器边框的距离
           this.y=e.clientY;
           this.l=this.el.offsetLeft; //元素的宽高
           this.t=this.el.offsetTop;
           
           this.MOVE=processThis(this.move,this);
           this.UP=processThis(this.up,this);
    
            //分浏览器来进行事件调用-背景背选中的问题和失去焦点的问题;
            if(this.el.setCapture){
            // 标准浏览器
                this.el.setCapture();
                on(this.el,'mousemove',this.MOVE);
                on(this.el,'mouseup',this.UP);
             }else{
                   on(document,'mousemove',this.MOVE);
                   on(document,'mouseup',this.UP);
                //阻止默认事件
                   e.preventDefault();
              }
              //跟拖拽无关的:按下的时候,停止定时器
            clearTimeout(this.xtimer);
            clearTimeout(this.ytimer);
         }
     move(e){
        // 求出最新的位置
        var l=e.clientX-this.x+this.l;
        var t=e.clientY-this.y+this.t;
        // 最大的边界
        var maxL=(document.documentElement.clientWidth||document.body.clientWidth)-this.el.offsetWidth;
        var maxT=(document.documentElement.clientHeight||document.body.clientHeight)-this.el.offsetHeight;
        // 边界判断
        if(l<=0){
           l=0;
         }else if(l>=maxL){
             l=maxL;
          }
        
        if(t<=0){
           t=0;
         }else if(t>=maxT){
            t=maxT;
          }
    
        this.el.style.left=l+'px';
        this.el.style.top=t+'px';
      }
    
      up(){
            //IE释放焦点捕获
            if(this.el.releaseCapture){
                this.el.releaseCapture();
                off(this.el,'mousemove',this.MOVE);
                off(this.el,'mouseup',this.UP);
            }else{
                off(document,'mousemove',this.MOVE);
                off(document,'mouseup',this.UP);
            }
       }
     }
    

    event.js 事件函数

    事件的绑定和解除绑定 改变事件函数里面的this

    //给自己事件池绑定许多方法,即都绑到数组中去了;
    
    function on(ele,type,fn){
        // 浏览器的判断
        if(ele.addEventListener){
            ele.addEventListener(type.fn,false);
         }else{
            // IE浏览器
            if(!ele['on'+type]){
                ele['on'+type]=[]; // 给ele['on'+type]属性上赋值一个空数组
                 //这里用来解决run的重复绑定问题;
                // 绑定事件
                ele.attachEvent('on'+type,function(){
                    run.call(ele);
                 })
             }
              
               //解决重复问题
            for(var i=0; i<ele['on'+type].length; i++){
                if(ele['on'+type][i]==fn) return;
            }
            a.push(fn);
            
          }
     }
    
    //拿到数组,顺序调用(是函数,才能调用)
    function run(){
       var e=window.event;
       e.target=e.srcElement;
       e.pageX=(document.documentElement.scrollLeft||document.body.scrollLeft)+e.clientX;
       e.pageY=(document.documentElement.scrollTop||document.body.scrollTop)+e.clientY;
        e.preventDefault=function(){
            e.returnValue=false;
        };
        e.stopPropagation=function(){
            e.cancelBubble=true;
        };
    
        if(this['on'+e.type].length){
             for(var i=0; i<this['on'+e.type].length; i++){
                if(typeof this['on'+e.type][i]==='function'){
                    this['on'+e.type][i].call(this,e);
                }else{
                    this['on'+e.type].splice(i,1);
                    i--;
                }
            }
        
         }
     }
    //拿到数组,循环匹配,匹配到谁,赋值为null;
    
    function off(ele,type,fn){
       if(ele.removeEventListener){
          ele.removeEventListener(type,fn,false);
        }else{//IE
            var a=ele['on'+type];
            if(a.length){
                for(var i=0; i<a.length; i++){
                    if(a[i]===fn){
                        a[i]=null;
                        break;
                    }
                }
            }
        }
     }
    
    
    // 改变事件函数里面的this指向
    function processThis(fn,argThis){
         return function(e){
            e=e||window.event;
            fn.call(argThis,e);
          }
     }
    

    测试代码

    <script>
       var oDiv=document.getElementById('div');
        var drag1=new Drag({
            el:oDiv
        });
    drag1.on('myDown',fn1).on('myDown',fn2).on('myDown',fn3).on('myMove',fn4).on('myMove',fn5).on('myUp',fn6).on('myUp',fn7);
        function fn1(){
            console.log('down行为下的:'+1)
        }
        function fn2(){
            console.log('down行为下的:'+2)
        }
        function fn3(){
            console.log('down行为下的:'+3)
        }
        function fn4(){
            console.log('move行为下的:'+4)
        }
        function fn5(){
            console.log('move行为下的:'+5)
        }
        function fn6(){
            console.log('up行为下的:'+6)
        }
        function fn7(){
            console.log('up行为下的:'+7)
        }
    </script>
    

    相关文章

      网友评论

        本文标题:面向对象的拖拽

        本文链接:https://www.haomeiwen.com/subject/bifhrxtx.html