好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

前端工程师小A学习JS的旅程

前端工程师小A学习JS的旅程

前端工程师小A学习JS的旅程

前端工程师小A学习JS的旅程

 

 

 

在网页里, 拖拽效果是很常见的形式,实现起来也比较简单,但是这么简单的代码,却能体现出很多前端开发工程湿的JS能力,我们来看看小A工程师的实现路程:

HTML代码:

 <!  DOCTYPE HTML  > 
 <  html  > 
 <  head  > 
     <  title  > 拖拽效果 </  title  > 
     <  meta   charset  ="UTF-8"  > 
     <  meta   http-equiv  ="X-UA-Compatible"   content  ="IE=Edge,chrome=1"  > 
     <  style   type  ="text/css"  >  
        #drag_box  {  width  :   150px  ;  height  :   150px  ;  background-color  :   #ff0000  ;  position  :   absolute  ;  margin  :   0  ;  top  :   80px  ;  left  :   0  ;  }  
        #diy,#dix  {  width  :   70px  ;  display  :   inline-block  ;  height  :   30px  ;  } 
     </  style  > 
 </  head  > 
 <  body  > 
     <  span   id  ="dix"  > X:0px </  span  > 
     <  input   type  ="button"   value  ="锁定X轴"   id  ="closeX"   data-open  ="true"  > 
     <  br  /> 
     <  span   id  ="diy"  > Y:80px </  span  > 
     <  input   type  ="button"   value  ="锁定Y轴"   id  ="closeY"   data-open  ="true"  > 
     <  div   id  ="drag_box"  ></  div  >     
    
 </  body  >     
 </  html  > 

JS代码:

小A的拖拽JS代码第一版

<script type="text/javascript">
     var  closeX=document.getElementById("closeX"),closeY=document.getElementById("closeY" );
    closeX.onclick = function  (){
          if ( this .getAttribute("data-open")=="true" ){
              this .setAttribute("data-open","false" );
              this .value="解开X轴" ;
        }  else  {
              this .setAttribute("data-open","true" );
              this .value="锁定X轴" ;
        }            
    }
    closeY.onclick = function  (){
          if ( this .getAttribute("data-open")=="true" ){
              this .setAttribute("data-open","false" );
              this .value="解开Y轴" ;
        }  else  {
              this .setAttribute("data-open","true" );
              this .value="锁定Y轴" ;
        }            
    }
      var  box=document.getElementById('drag_box' );        
      var  x=y=0 ;
      var  dix=document.getElementById("dix"),diy=document.getElementById("diy" );
    box.onmousedown = function  (event){
          var  event=event|| window.event;
        x =event.clientX- this  .offsetLeft;
        y =event.clientY- this  .offsetTop;
          this .style.cursor="move" ;
          var  that =  this  ;
        document.onmousemove = function  (event){
              var  event=event|| window.event;
              var  le=event.clientX-x,to=event.clientY- y;
              var  maxL = document.documentElement.clientWidth -  box.offsetWidth;
              var  maxT = document.documentElement.clientHeight -  box.offsetHeight;
              if (le<0 ){
                le =0 
            }  else   if (le> maxL){
                le = maxL;
            }
              if (to<80 ){
                to =80 
            }  else   if (to> maxT){
                to = maxT;
            }                    
              if (closeX.getAttribute("data-open")=="true" ){
                that.style.left =le+"px" ;    
                dix.innerHTML ="X:"+le+"px" ;                        
            }
              if (closeY.getAttribute("data-open")=="true" ){
                that.style.top =to+"px" ;    
                diy.innerHTML ="Y:"+to+"px" ;
            }                        
              if  (that.releaseCapture){
                that.releaseCapture();
            }                    
              return   false  ;                                
        }
          this .onmouseup= function  (){
            document.onmousemove = null  ;
            document.onmouseup  =  null  ;
              this .style.cursor="default" ;
              if ( this  .releaseCapture){
                  this  .releaseCapture();
            }                
              return   false  ;
        }
          if ( this  .releaseCapture){
                  this  .releaseCapture();
            }                
          return   false  ;
    }  
 </script>

这是小A初学JS一个月写出来的JS代码,完美实现了拖拽的功能,并且也能也能注意在适当的时候阻止事件的默认行为,还能用上 if(this.releaseCapture){ this.releaseCapture(); }这样的语句来防止鼠标离开拖拽BOX。对于小A来说,学习一个月能写出这样的代码来已经实属不易,我们也不得不承认小A是一个学习能力很强的前端工程师。

       又学习了一个月小A学到了js的封装,于是重新看了看上面的代码,觉得处理锁定X轴和锁定Y轴的代码有些重复,而且拖拽的对象可能会发生变化,于是小A改造了一下上面的代码,创建了两个方法函数 drag和closexy把主体功能封转在两个函数里面:

小A的拖拽JS代码第二版

<script type="text/javascript">
     function   drag (box) {
          var  x=y=0 ;
          var  dix=document.getElementById("dix"),diy=document.getElementById("diy" );
        box.onmousedown = function  (event){
              var  event=event|| window.event;
            x =event.clientX- this  .offsetLeft;
            y =event.clientY- this  .offsetTop;
              this .style.cursor="move" ;
              var  that =  this  ;
            document.onmousemove = function  (event){
                  var  event=event|| window.event;
                  var  le=event.clientX-x,to=event.clientY- y;
                  var  maxL = document.documentElement.clientWidth -  box.offsetWidth;
                  var  maxT = document.documentElement.clientHeight -  box.offsetHeight;
                  if (le<0 ){
                    le =0 
                }  else   if (le> maxL){
                    le = maxL;
                }
                  if (to<80 ){
                    to =80 
                }  else   if (to> maxT){
                    to = maxT;
                }                    
                  if (closeX.getAttribute("data-open")=="true" ){
                    that.style.left =le+"px" ;    
                    dix.innerHTML ="X:"+le+"px" ;                        
                }
                  if (closeY.getAttribute("data-open")=="true" ){
                    that.style.top =to+"px" ;    
                    diy.innerHTML ="Y:"+to+"px" ;
                }                        
                  if  (that.releaseCapture){
                    that.releaseCapture();
                }                    
                  return   false  ;                                
            }
              this .onmouseup= function  (){
                document.onmousemove = null  ;
                document.onmouseup  =  null  ;
                  this .style.cursor="default" ;
                  if ( this  .releaseCapture){
                      this  .releaseCapture();
                }                
                  return   false  ;
            }
              if ( this  .releaseCapture){
                      this  .releaseCapture();
                }                
              return   false  ;
        }
    }
      function   closexy(xy,obj){            
          if (obj.getAttribute("data-open")=="true" ){
            obj.setAttribute( "data-open","false" );
            obj.value ="解开"+xy+"轴" ;
        }  else  {
            obj.setAttribute( "data-open","true" );
            obj.value ="锁定"+xy+"轴" ;
        }            
    }
      var  box=document.getElementById('drag_box' );        
    drag(box);
      var  closeX=document.getElementById("closeX"),closeY=document.getElementById("closeY" );
    closeX.onclick = function  (){
        closexy( "X", this  );
    }
    closeY.onclick = function  (){
        closexy( "Y", this  );
    }
 </script>

这样一看,代码量减少了许多,而且显得也比较调理,更重要的是封转后的方法在随意的对象上都可以调用,简单、方便!此时的小A学习js的激情高涨,于是就更加勤奋的学习!

     又不知过了多久。小A的js水平有了大幅提高,这个时候小A回头看之前写过的拖拽代码,觉得有很多不妥的地方,比如:没有注意命名空间,没有成模块化、如果拖拽的外围边界不是body了怎么变、如果拖拽的范围变化了呢,拖拽的锁定可不可以做成开放性的呢。基于这些问题,于是小A觉得完全可以把拖拽功能做成一个拖拽库,开放接口,以应付千变万化的拖拽效果和需求,所以小A又写了第三版的拖拽JS代码:

小A的拖拽JS代码第三版

<script type="text/javascript">
     /*   *
     * * dragBox:拖动对象,可以是对象的ID;
     * * options:参数;
     * * maxContainer:设置拖动外围box,默认为body;
     * * minL:离外围边界左边最小距离,默认为0;
     * * maxL:离外边界左边最大距离,默认body的宽度-拖动对象宽度;
     * * minT:离外围边界上边最小距离,默认为0;
     * * maxT:离外围边界最大高度,默认为body高度-拖动对象高度;
     * * lockx:是否锁定X轴,默认不锁定;
     * * locky:是否锁定Y轴,默认不锁定;
     * * onStart:开始拖动回调函数;
     * * onMove:拖动过程中回调函数;
     * * onStop:拖动结束回调函数;
      */ 
         function   Drag(){
              this .init.apply( this  ,arguments);
        }
        Drag.prototype = {
            init:  function  (dragBox,options){
                  this .dragBox= this  .$(dragBox);
                  this  .setOptions(options);
                  this ._moveDrag= this .bind( this , this  .moveDrag);    
                  this ._stopDrag= this .bind( this , this  .stopDrag);        
                  this .maxContainer =  this .options.maxContainer||document.documentElement ||  document.body;
                  this .minL= this .options.minL||0 ;
                  this .maxL= this .options.maxL||Math.max( this .maxContainer.clientWidth, this .maxContainer.scrollWidth)- this  .dragBox.offsetWidth;
                  this .minT= this .options.minT||0 ;
                  this .maxT= this .options.maxT||Math.max( this .maxContainer.clientHeight, this .maxContainer.scrollHeight)- this  .dragBox.offsetHeight;
                  this .lockx =  this .options.lockx|| false  ;
                  this .locky =  this .options.locky|| false  ;
                  this .onStart= this .options.onStart|| null  ;
                  this .onMove= this .options.onMove|| null  ;
                  this .onStop= this .options.onStop|| null  ;
                  this .addHandle( this .dragBox, "mousedown",  this .bind( this ,  this  .startDrag));    
                  this  .haslayout();            
            },
            haslayout:  function  (){
                  this .dragBox.style.left= this .minL+"px" ;
                  this .dragBox.style.top= this .minT+"px" ;
            },
            startDrag:  function  (event){
                  var  event=event|| window.event;
                  this ._x=event.clientX- this  .dragBox.offsetLeft;
                  this ._y=event.clientY- this  .dragBox.offsetTop;
                  this .addHandle(document,"mousemove", this  ._moveDrag);
                  this .addHandle(document,"mouseup", this  ._stopDrag);
                  this  .preventDefault(event);
                  this .dragBox.setCapture &&  this  .dragBox.setCapture();
                  if ( typeof  onStart==="function" ){
                      this  .onStart();
                }                
            },
            moveDrag:  function  (event){
                  var  event=event|| window.event;
                  this .dragBox.style.cursor = "move" ;
                  var  le=event.clientX- this ._x,to=event.clientY- this  ._y;                
                  if (le< this  .minL){
                    le = this  .minL
                }  else   if (le> this  .maxL){
                    le = this  .maxL;
                }
                  if (to< this  .minT){
                    to = this  .minT;
                }  else   if (to> this  .maxT){
                    to = this  .maxT;
                }
                  if (! this  .lockx){
                      this .dragBox.style.left=le+"px" ;
                }
                  if (! this  .locky){
                      this .dragBox.style.top=to+"px" ;
                }
                  this  .preventDefault(event);
                  this .dragBox.setCapture &&  this  .dragBox.setCapture();
                  if ( typeof  onMove==="function" ){
                      this  .onMove();
                }
            },
            stopDrag:  function  (){
                  this .removeHandle(document,"mousemove", this  ._moveDrag);
                  this .removeHandle(document,"mouseup", this  ._stopDrag);
                  this .dragBox.style.cursor = "default" ;
                  this .dragBox.setCapture &&  this  .dragBox.setCapture();
                  if ( typeof  onStop==="function" ){
                      this  .onStop();
                }
            },
            $:  function  (id){
                  return   typeof  id=="string" ?  document.getElementById(id):id;
            },
            addHandle:  function  (element,type,handler){
                  if  (element.addEventListener){
                    element.addEventListener(type,handler,  false  );
                }  else   if  (element.attachEvent){
                    element.attachEvent( "on"+ type,handler);
                }  else  {
                    element[ "on"+type]= handler;
                }
            },
            removeHandle:  function  (element,type,handler){
                  if  (element.removeEventListener){
                    element.removeEventListener(type,handler,  false  );
                }  else   if  (element.detachEvent){
                    element.detachEvent( "on"+ type,handler);
                }  else  {
                    element[ "on"+type]= null  ;
                }
            },
            preventDefault:  function  (event){
                  if  (event.preventDefault){
                    event.preventDefault();
                }  else  {                    
                    event.returnValue = false  ;
                }
            },
            setOptions :   function  (options){
                  this .options = {};
                  for  ( var  p  in  options)  this .options[p] =  options[p];
            },
            bind :   function   (object, fnHandler){
                  return   function   (){
                      return   fnHandler.apply(object, arguments)    
                }
            }
        };    
          //  应用 
         var  box=document.getElementById("drag_box" );
          var  Mydrag= new   Drag(box,{
            minT: 10 ,
            maxT: 100 ,
            lockx:  true  
        });
     </script>

这样,一个功能齐全的拖拽库就这样漂亮的诞生了!拖拽库开放接口很齐全,代码页很规范。从此小A就不用害怕任何拖拽功能需求了!

        从小A学习js的旅程,我们可以看出,学习JS是一个循序渐进的过程,看似简单的功能,从最开始的实现功能,到不断改进,一直到最后写成一个插件,可以有很多版本,而这些不断改进的过程正是学习JS最好的方法!

 

 

 

标签:  javascript

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于前端工程师小A学习JS的旅程的详细内容...

  阅读:38次