JS闯关之路我们就爱程序媛

面向对象的拖拽

2017-08-10  本文已影响8人  icessun

面向对象中,尽量避免函数嵌套;公共用的东西放在构造函数(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>
上一篇 下一篇

猜你喜欢

热点阅读