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

  • 相关阅读:
    写给理工科人看的乐理(一)声学基础
    魔方最少记忆还原法
    甲乙两人互猜数字(鬼谷子问题)的逻辑推理与算法建模
    模板元编程实现素数判定
    UVa OJ 194
    UVa OJ 175
    UVa OJ 197
    UVa OJ 180
    UVa OJ 140
    判断input或者div.span等标签是否存在
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3116605.html
Copyright © 2011-2022 走看看