zoukankan      html  css  js  c++  java
  • 前端工程师小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

  • 相关阅读:
    Android 开发 深入理解Handler、Looper、Messagequeue 转载
    Android 开发 Handler的基本使用
    Java 学习 注解
    Android 开发 AlarmManager 定时器
    Android 开发 框架系列 百度语音合成
    Android 开发 框架系列 Google的ORM框架 Room
    Android 开发 VectorDrawable 矢量图 (三)矢量图动画
    Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
    Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图
    Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3116605.html
Copyright © 2011-2022 走看看