• javascript 拖放效果


     

    最近一直在看javascript的书籍,有些东西在书上看着貌似理解了,但是在真正动手实践时,其实有些细节你根本不了解。所以看起来就算是一个简单的效果,写起来也未必简单,就算写起来简单,写的代码也未必规范、可维护性等等。无奈,一直学习编程以来都是眼高手低,导致什么都写不出来。在自己没有足够的功底写出好的代码出来,学习大牛的代码也是一直高效的方式。以下是一个拖放的效果,参考的代码,重构以下,加以理解学习。

    首先来看效果:

    拖动div

          
    拖放状态:未开始

    【程序说明】

    拖动原理:其实就是在拖动块上监听mousedown事件,鼠标点击时,通过事件对象获取对应的坐标参数。然后鼠标移动时再监听document上的mousemove事件,获取鼠标的clientX 和clientY坐标然后设置拖动块的left 和 top。

    首先是监听mousedown事件

    EventUtil.addEventHandler(this.Drag, "mousedown", BindAsEventListener(this, this.Start)); 

    然后在Start上添加mousemove 和 mouseup 事件

    //监听mousemove 和 mouseup事件
    EventUtil.addEventHandler(document, "mousemove", this._fM);
    EventUtil.addEventHandler(document, "mouseup", this._fS);

    鼠标移动时,设置拖动块的left 和 top 属性 :

     if(!this.LockX)this.Drag.style.left = iLeft + "px";
     if(!this.LockY)this.Drag.style.top = iTop + "px"; 

    水平和垂直锁定:通过判断LockX 和lockY属性来限制对于的top 和 left 属性即可。

    范围限制锁定:通过计算容器的宽高和拖动块的宽高差值来设定最大left值和top值,来限制拖动块的left值和top值会在一定的范围里。

    完整DEMO:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>JavaScript拖放效果</title>
        <style type="text/css">
         
        </style>
    </head>
    <body>
        <div id="drag-wrap" style="height: 300px;margin:10px;border:5px solid #FF8000;background:#8080C0;position: relative;">
             <div class="draggable" id="drag" style="100px;height: 100px;position: absolute;top: 100px;left:100px;background:#eee;border:1px solid #aceaac;cursor: move;">拖动div</div>
        </div>
        <input id="idReset" type="button" value="复位" />
        <input id="idLock" type="button" value="锁定全部" />
        <input id="idLockX" type="button" value="锁定水平" />
        <input id="idLockY" type="button" value="锁定垂直" />
        <input id="idLimit" type="button" value="范围锁定" />
        <input id="idLimitOff" type="button" value="取消范围锁定" />
        <br />拖放状态:<span id="idShow">未开始</span>
        <script type="text/javascript">
            /**
              *工具函数
              */
             var isIE = (document.all) ? true : false ;
     
             var $$ = function(id){
                 return "string" == typeof id ? document.getElementById(id) : id;
             };
     
             var Class = {
                create: function() {
                    return function() { this.initialize.apply(this, arguments); }
                }
            };
     
            var Extend = function(destination,source){
                for(var property in source){
                    destination[property] = source[property];
                }
            };
     
            var BindAsEventListener = function(object,func){
                return function(event){
                    return func.call(object,event || window.event);
                }
            };
     
            var Bind = function(object,func){
                return function(){
                    return func.apply(object,arguments);
                }
            };
     
             /**
              *跨浏览器事件对象
              */
            var EventUtil = {
                //事件注册处理程序
                addEventHandler:function(oTarget,sEventType,fnHandler){
                     if(oTarget.addEventListener){
                         oTarget.addEventListener(sEventType,fnHandler,false);
                     }else if(oTarget.attachEvent){
                         oTarget.attachEvent("on"+sEventType,fnHandler);
                     }else{
                         oTarget["on"+sEventType] = fnHandler;
                     }
                 },
                 //事件移除处理程序
                 removeEventHandler:function(oTarget,sEventType,fnHandler){
                     if(oTarget.removeEventListener){
                         oTarget.removeEventListener(sEventType,fnHandler,false);
                     }else if(oTarget.detachEvent){
                         oTarget.detachEvent("on"+sEventType,fnHandler);
                     }else{
                         oTarget["on"+sEventType] = null;
                     }
                 },
                 getEvent:function(event){
                     return event ? event : window.event;
                 },
                 getTarget:function(event){
                     return event.target || event.srcElement;
                 }
            };   
     
            /**
              *拖放程序
             */
             var Drag= Class.create();
     
             Drag.prototype = {
                 //初始化对象
                 initialize:function(drag,options){
                     this.Drag = $$(drag);//拖放对象
                     this._x = this._y = 0;//记录鼠标相对于拖放对象的位置
                     //事件对象(用于绑定移除事件)
                     this._fM = BindAsEventListener(this, this.Move);
                    this._fS = Bind(this, this.Stop);
                    this.Drag.style.position = "absolute";
                    this.marginLeft = this.marginTop = 0;//记录margin
                    //设置参数
                    this.setOptions(options);
                    //获取相关参数及类型转换
                    this.Limit = !!this.options.Limit;//转换为布尔型
                    this.mxLeft = parseInt(this.options.mxLeft);
                    this.mxRight = parseInt(this.options.mxRight);
                    this.mxTop = parseInt(this.options.mxTop);
                    this.mxBottom = parseInt(this.options.mxBottom);
     
                    this.Lock = !!this.options.Lock;
                    this.LockX = !!this.options.LockX;
                    this.LockY = !!this.options.LockY;
     
                    this.onStart = this.options.onStart;
                    this.onMove = this.options.onMove;
                    this.onStop = this.options.onStop;
     
                    this._Handle = $$(this.options.Handle) || this.Drag;
                    this._mxContainer = $$(this.options.mxContainer) || null;
                    //监听拖动对象mousedown事件
                    EventUtil.addEventHandler(this.Drag, "mousedown", BindAsEventListener(this, this.Start));
     
                 },
                 //准备拖动   
                 Start:function(oEvent){
                     if(this.Lock){return;}//如果锁定则不执行
                     //记录mousedown触发时鼠标相对于拖放对象的位置
                     this._x = oEvent.clientX - this.Drag.offsetLeft;
                    this._y = oEvent.clientY - this.Drag.offsetTop;
                    //监听mousemove 和 mouseup事件
                    EventUtil.addEventHandler(document, "mousemove", this._fM);
                    EventUtil.addEventHandler(document, "mouseup", this._fS);
                 },   
                 //拖动
                 Move:function(oEvent){
                     //设置移动参数
                     var iLeft = oEvent.clientX - this._x , iTop = oEvent.clientY - this._y;
                     //设置范围限制
                     if(this.Limit){
                         //设置范围参数
                        var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
                        //如果设置了容器,再修正范围参数
                        if(!!this._mxContainer){
                            mxLeft = Math.max(mxLeft, 0);
                            mxTop = Math.max(mxTop, 0);
                            mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
                            mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
                        };
                        //修正移动参数
                        iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft);
                        iTop = Math.max(Math.min(iTop, mxBottom - this.Drag.offsetHeight), mxTop);
                     }
                     //XY锁定
                     if(!this.LockX)this.Drag.style.left = iLeft + "px";
                    if(!this.LockY)this.Drag.style.top = iTop + "px";
                    //执行附加程序
                    this.onMove();
                 },
                 //停止拖动
                 Stop:function(){
                    EventUtil.removeEventHandler(document, "mousemove", this._fM);
                    EventUtil.removeEventHandler(document, "mouseup", this._fS);
                    //执行附加程序
                    this.onStop();
                 },
                 //设置默认参数
                 setOptions:function(options){
                     this.options = {//默认值
                        Handle:            "",//设置触发对象(不设置则使用拖放对象)
                        Limit:            false,//是否设置范围限制(为true时下面参数有用,可以是负数)
                        mxLeft:            0,//左边限制
                        mxRight:        9999,//右边限制
                        mxTop:            0,//上边限制
                        mxBottom:        9999,//下边限制
                        mxContainer:    "",//指定限制在容器内
                        LockX:            false,//是否锁定水平方向拖放
                        LockY:            false,//是否锁定垂直方向拖放
                        Lock:            false,//是否锁定
                        Transparent:    false,//是否透明
                        onStart:        function(){},//开始移动时执行
                        onMove:            function(){},//移动时执行
                        onStop:            function(){}//结束移动时执行
                    };
                    Extend(this.options, options || {});
                 }
             };
     
            //初始化拖动对象
            var drag = new Drag('drag',{mxContainer:'drag-wrap',Limit:true,
                    onStart: function(){ $$("idShow").innerHTML = "开始拖放"; },
                    onMove: function(){ $$("idShow").innerHTML = "left:"+this.Drag.offsetLeft+";top:"+this.Drag.offsetTop; },
                    onStop: function(){ $$("idShow").innerHTML = "结束拖放"; }
                    });
            $$("idReset").onclick = function(){
                drag.Limit = true;
                drag.mxLeft = drag.mxTop = 0;
                drag.mxRight = drag.mxBottom = 9999;
                drag.LockX = drag.LockY = drag.Lock = false;
                $$("idShow").innerHTML = "复位";
            }
            $$("idLock").onclick = function(){ drag.Lock = true;$$("idShow").innerHTML = "锁定全部";}
            $$("idLockX").onclick = function(){ drag.LockX = true; $$("idShow").innerHTML = "锁定水平";}
            $$("idLockY").onclick = function(){ drag.LockY = true; $$("idShow").innerHTML = "锁定垂直";}
            $$("idLimit").onclick = function(){     drag.mxRight = drag.mxBottom = 200;drag.Limit = true;$$("idShow").innerHTML = "范围锁定"; }
            $$("idLimitOff").onclick = function(){ drag.Limit = false; $$("idShow").innerHTML = "取消范围锁定";}
        </script>
    </body>
    </html>
  • 相关阅读:
    2021 0309-1 准备工作
    课程总结
    第十四周课程总结&实验报告
    第十三周课程总结
    第十二周课程总结
    第十一周课程总结
    第十周课程总结
    2019春总结作业
    第十二周作业
    第十一周作业
  • 原文地址:https://www.cnblogs.com/libaoli/p/5052003.html
Copyright © 2020-2023  润新知