拖拽封装

/**
 * draggbale 拖拽元素
 * 1.0版本
 * 使用方式:
 * draggable(ele, {
 *          x : false, //表示水平方向是否可拖拽
 *          y : true, //表示垂直方向是否可拖拽
 *          limit : true, //表示活动范围是否限制在定位父元素内
 *          paddingLeft : 0,  //增加填充,即进一步缩小活动范围
            paddingRight :0,  //增加填充,即进一步缩小活动范围
            paddingTop : 0,  //增加填充,即进一步缩小活动范围
            paddingBottom  : 0,  //增加填充,即进一步缩小活动范围
            maringLeft : 0, //设置margin值,可以消除由于margin带来的拖拽误差,不填则可能会受影响
            marginTop : 0, //设置margin值,可以消除由于margin带来的拖拽误差,不填则可能会受影响
            callback : function(section, distance){
                  回调函数,在拖拽过程中不断触发
                  两个参数分别为:拖拽元素的可活动范围大小,拖拽元素在可活动范围内的坐标
                  section包括,minLeftmaxLeftminTopmaxTop
                  distance包括, xy
                  绑定了this,回调函数中可以直接使用this来指向拖拽元素ele本身
            }
 * })
 * */
 
(function(){
      //获取元素页面绝对位置
      function offsetPage(obj) {
            var _left = obj.offsetLeft;
            var _top = obj.offsetTop;
            while(obj.offsetParent) {
                  _left += obj.offsetParent.offsetLeft;
                  _top += obj.offsetParent.offsetTop;
                  obj = obj.offsetParent;
            }
            return {
                  "left": _left,
                  "top": _top
            };
      }
      
      //获取样式
      function getStyle(ele, attr){
            if(ele.currentStyle) {
                  return ele.currentStyle[attr];
            } else {
                  return getComputedStyle(ele)[attr];
            }
      }
      
      //函数的事件添加
      var addEvent = (function() {
            if(window.VBArray) {
                  return function(obj, eventname, func) {
                        obj.attachEvent("on" + eventname, func);
                  }
            } else {
                  return function(obj, eventname, func, isCapture) {
                        obj.addEventListener(eventname, func, !!isCapture);
                  }
            }
      })();
      
      //合并对象
      function merge(a, b){
            if(!b) {
                  return a;
            }
            var newobj = {};
            for(var attr in a){
                  newobj[attr] = a[attr];
            }
            for(var attr in b) {
                  newobj[attr] = b[attr];
            }
            return newobj;
      }
      
      window.draggable = function(ele, _options) {
            //如果定位方式不是absolute,直接返回
            if(getStyle(ele,"position") != "absolute" && getStyle(ele,"position") != "fixed") return;
            
            var default_options = {
                  x : true,
                  y : true,
                  limit : true,
                  paddingLeft : 0,
                  paddingRight :0,
                  paddingTop : 0,
                  paddingBottom  : 0,
                  marginLeft : 0,
                  marginTop : 0,
                  callback : function(){}
            };
            
            var options = merge(default_options, _options);
            
            
            
            /*
            if(options.limit) { //如果用户设置了限定范围
                  //计算元素的坐标取值范围
                  var section = {
                        minLeft : options.paddingLeft - options.marginLeft,
                        maxLeft : ele.offsetParent.offsetWidth - ele.offsetWidth - options.paddingRight - options.marginLeft,
                        minTop : options.paddingTop - options.marginTop,
                        maxTop : (ele.offsetParent.offsetHeight - ele.offsetHeight) - options.paddingBottom - options.marginTop
                  }
            }*/
            
            //console.log(section);
            
            var startPoint = {
                  x: offsetPage(ele).left,
                  y: offsetPage(ele).top
            }
            
            addEvent(ele, "mousedown", function(e){
                  var e = e || event;
                  
                  //计算鼠标和要拖拽元素的相对位置
                  var mouse = {
                        pageX : e.clientX + document.body.scrollLeft || document.documentElement.scrollLeft,
                        pageY : e.clientY + document.body.scrollTop || document.documentElement.scrollTop
                  }
                  mouse.offsetX = mouse.pageX - offsetPage(ele).left + options.marginLeft;
                  mouse.offsetY = mouse.pageY - offsetPage(ele).top + options.marginTop;
                  
                  //添加移动事件
                  addEvent(document, "mousemove", move);
                  function move(e){
                        var e = e || event;
                        //计算鼠标当前的页面坐标pageX/Y
                        var currentPos = {
                              pageX : e.clientX + document.body.scrollLeft || document.documentElement.scrollLeft,
                              pageY : e.clientY + document.body.scrollTop || document.documentElement.scrollTop
                        }
                        
                        var section = {
                              minLeft : options.paddingLeft - options.marginLeft,
                              maxLeft : ele.offsetParent.offsetWidth - ele.offsetWidth - options.paddingRight - options.marginLeft,
                              minTop : options.paddingTop - options.marginTop,
                              maxTop : (ele.offsetParent.offsetHeight - ele.offsetHeight) - options.paddingBottom - options.marginTop
                        }
                        
                        
                        if(options.limit) { //如果限定范围
                              if(options.x) { //如果允许水平拖动
                                    ele.style.left = Math.min(section.maxLeft ,Math.max(section.minLeft, currentPos.pageX - offsetPage(ele.offsetParent).left - mouse.offsetX)) + "px";
                              }
                              if(options.y) { //如果允许垂直拖动
                                    ele.style.top = Math.min(section.maxTop ,Math.max(section.minTop, currentPos.pageY - offsetPage(ele.offsetParent).top - mouse.offsetY)) + "px";
                              }
                        } else {
                              if(options.x) {
                                    ele.style.left = currentPos.pageX - offsetPage(ele.offsetParent).left - mouse.offsetX + "px";
                              }
                              if(options.y) {
                                    ele.style.top = currentPos.pageY - offsetPage(ele.offsetParent).top - mouse.offsetY + "px";
                              }
                        }
                        options.callback.call(ele, section, {x:offsetPage(ele).left - startPoint.x, y:offsetPage(ele).top - startPoint.y});
                  }
                  addEvent(document, "mouseup", function(e){
                        //document.detach("mousemove", move);
                        document.removeEventListener("mousemove", move);
                  });
            });
            
      }
      
})();
 
原文地址:https://www.cnblogs.com/tis100204/p/10310076.html