Arce 发表于 2021-7-30 17:18:24

拖拽插件jquery.dad.js


带删除功能:<!DOCTYPE html>            
<html>            
<head>            
    <meta charset="UTF-8">            
    <title>拖拽插件jquery.dad.js</title>         
    <style type="text/css">
      .dad-noSelect,.dad-noSelect *{
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            cursor: -webkit-grabbing !important;
            cursor: -moz-grabbing !important;
      }

      .dad-container{
            position: relative;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
      }
      .dad-container::after{
            content: '';
            clear: both !important;
            display: block;
      }
      .dad-active .dad-draggable-area{
            cursor: -webkit-grab;
            cursor: -moz-grab;
      }
      .dad-draggable-area>*,.dad-draggable-area img{
            pointer-events: none;
      }
      .dads-children.active{
            pointer-events: none;
      }
      .dads-children-clone{
            opacity: 1;
            z-index: 9999;
            pointer-events: none;
      }
      .dads-children-placeholder{
            pointer-events: none;
            overflow: hidden;
            position: absolute !important;
            box-sizing: border-box;
            border:4px dashed #639BF6;
            margin:5px;
            text-align: center;
            color: #639BF6;
            font-weight: bold;
      }   
      .daddy>div {
            box-sizing: border-box;
            width: 20%;
            padding: 5px;
            float: left;
            display: block;
            position: relative;
      }
      .daddy>div>div {
            display: block;
            height: 120px;
            line-height: 120px;
            text-align: center;
            font-size: 30px;
            font-weight: bold;
            background: #639BF6;
            color: white;
            font-family: "Arial", sans-serif;
      }
      .m-delete{pointer-events: auto;}
    </style>
</head>            
<body>   
ccs文件和js文件可以去GitHub上下载,下载地址是:https://github.com/williammustaffa/jquery.dad.js
本实例是直接把源代码都复制过来了
    <div id="daddy" class="dad daddy">
      <div>
            <div>1</div>
            <input type="button" value="删除" class="m-delete js-delete">
      </div>
      <div>
            <div>2</div>
            <input type="button" value="删除" class="m-delete js-delete">
      </div>
      <div>
            <div>3</div>
            <input type="button" value="删除" class="m-delete js-delete">
      </div>
      <div>
            <div>4</div>
            <input type="button" value="删除" class="m-delete js-delete">
      </div>
      <div>
            <div>5</div>
            <input type="button" value="删除" class="m-delete js-delete">
      </div>
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <!-- <script src='jquery.dad.js'></script>    -->
    <script type="text/javascript">
      /*!
         * jquery.dad.js v1 (http://konsolestudio.com/dad)
         * Author William Lima
         */

      (function ($) {
          'use strict';
          var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

          $.fn.dad = function (opts) {
            var _this = this;

            var defaults = {
            target: '>div',
            draggable: false,
            placeholder: '',
            callback: false,
            containerClass: 'dad-container',
            childrenClass: 'dads-children',
            cloneClass: 'dads-children-clone',
            active: true,
            };

            var options = $.extend({}, defaults, opts);

            $(this).each(function () {
            var active = options.active;
            var $daddy = $(this);
            var childrenClass = options.childrenClass;
            var cloneClass = options.cloneClass;
            var jQclass = '.' + childrenClass;
            var $target = $daddy.find(options.target);
            var placeholder = options.placeholder;
            var callback = options.callback;
            var dragClass = 'dad-draggable-area';
            var holderClass = 'dads-children-placeholder';

            // HANDLE MOUSE
            var mouse = {
                x: 0,
                y: 0,
                target: false,
                clone: false,
                placeholder: false,
                cloneoffset: {
                  x: 0,
                  y: 0,
                },
                updatePosition: function (e) {
                  this.x = e.pageX;
                  this.y = e.pageY;
                },

                move: function (e) {
                  this.updatePosition(e);
                  if (this.clone !== false && _this.target !== false) {
                  this.clone.css({
                      left: this.x - this.cloneoffset.x,
                      top: this.y - this.cloneoffset.y,
                  });
                  }
                },
            };

            $(window).on('mousemove touchmove', function (e) {
                var ev = e;

                if (mouse.clone !== false && mouse.target !== false) e.preventDefault();

                if (supportsTouch && e.type == 'touchmove') {
                  ev = e.originalEvent.touches;
                  var mouseTarget = document.elementFromPoint(ev.clientX, ev.clientY);

                  $(mouseTarget).trigger('touchenter');
                }

                mouse.move(ev);
            });

            $daddy.addClass(options.containerClass);

            if (!$daddy.hasClass('dad-active') && active === true) {
                $daddy.addClass('dad-active');
            };

            _this.addDropzone = function (selector, func) {
                $(selector).on('mouseenter touchenter', function () {
                  if (mouse.target !== false) {
                  mouse.placeholder.css({ display: 'none' });
                  mouse.target.css({ display: 'none' });
                  $(this).addClass('active');
                  }
                }).on('mouseup touchend', function () {
                  if (mouse.target != false) {
                  mouse.placeholder.css({ display: 'block' });
                  mouse.target.css({ display: 'block' });
                  func(mouse.target);
                  dadEnd();
                  };

                  $(this).removeClass('active');
                }).on('mouseleave touchleave', function () {
                  if (mouse.target !== false) {
                  mouse.placeholder.css({ display: 'block' });
                  mouse.target.css({ display: 'block' });
                  }

                  $(this).removeClass('active');
                });
            };

            // GET POSITION FUNCTION
            _this.getPosition = function () {
                var positionArray = [];
                $(this).find(jQclass).each(function () {
                  positionArray[$(this).attr('data-dad-id')] = parseInt($(this).attr('data-dad-position'));
                });

                return positionArray;
            };

            _this.activate = function () {
                active = true;
                if (!$daddy.hasClass('dad-active')) {
                  $daddy.addClass('dad-active');
                }

                return _this;
            };

            // DEACTIVATE FUNCTION
            _this.deactivate = function () {
                active = false;
                $daddy.removeClass('dad-active');
                return _this;
            };

            // DEFAULT DROPPING
            $daddy.on('DOMNodeInserted', function (e) {
                var $thisTarget = $(e.target);
                if (!$thisTarget.hasClass(childrenClass) && !$thisTarget.hasClass(holderClass)) {
                  $thisTarget.addClass(childrenClass);
                }
            });

            $(document).on('mouseup touchend', function () {
                dadEnd();
            });

            // ORDER ELEMENTS
            var order = 1;
            $target.addClass(childrenClass).each(function () {
                if ($(this).data('dad-id') == undefined) {
                  $(this).attr('data-dad-id', order);
                }

                $(this).attr('data-dad-position', order);
                order++;
            });

            // CREATE REORDER FUNCTION
            function updatePosition(e) {
                var order = 1;
                e.find(jQclass).each(function () {
                  $(this).attr('data-dad-position', order);
                  order++;
                });
            }

            // END EVENT
            function dadEnd() {
                if (mouse.target != false &&mouse.clone != false) {
                  if (callback != false) {
                  callback(mouse.target);
                  }

                  var appear = mouse.target;
                  var desappear = mouse.clone;
                  var holder = mouse.placeholder;
                  var bLeft = 0;
                  var bTop = 0;

                  // Maybe we will use this in the future
                  //Math.floor(parseFloat($daddy.css('border-left-width')));
                  //Math.floor(parseFloat($daddy.css('border-top-width')));
                  if ($.contains($daddy, mouse.target)) {
                  mouse.clone.animate({
                      top: mouse.target.offset().top - $daddy.offset().top - bTop,
                      left: mouse.target.offset().left - $daddy.offset().left - bLeft,
                  }, 300, function () {
                      appear.css({
                        visibility: 'visible',
                      }).removeClass('active');
                      desappear.remove();
                  });
                  } else {
                  mouse.clone.fadeOut(300, function () {
                      desappear.remove();
                  });
                  }

                  holder.remove();
                  mouse.clone = false;
                  mouse.placeholder = false;
                  mouse.target = false;
                  updatePosition($daddy);
                }

                $('html, body').removeClass('dad-noSelect');
            }

            // UPDATE EVENT
            function dadUpdate(obj) {
                if (mouse.target !== false && mouse.clone !== false) {
                  var $origin = $('<span style="display:none"></span>');
                  var $newplace = $('<span style="display:none"></span>');

                  if (obj.prevAll().hasClass('active')) {
                  obj.after($newplace);
                  } else {
                  obj.before($newplace);
                  }

                  mouse.target.before($origin);
                  $newplace.before(mouse.target);

                  // UPDATE PLACEHOLDER
                  mouse.placeholder.css({
                  top: mouse.target.offset().top - $daddy.offset().top,
                  left: mouse.target.offset().left - $daddy.offset().left,
                  width: mouse.target.outerWidth() - 10,
                  height: mouse.target.outerHeight() - 10,
                  });

                  $origin.remove();
                  $newplace.remove();
                }
            }

            // GRABBING EVENT
            var jq = (options.draggable !== false) ? options.draggable : jQclass;
            $daddy.find(jq).addClass(dragClass);
            $daddy.on('mousedown touchstart', jq, function (e) {
                var isDelete = $(e.target).hasClass('js-delete');
                if(isDelete) {
                  return;
                }
                // For touchstart we must update "mouse" position
                if (e.type == 'touchstart') {
                  mouse.updatePosition(e.originalEvent.touches);
                }

                if (mouse.target == false && active == true && (e.which == 1 || e.type == 'touchstart')) {
                  var $self = $(this);

                  // GET TARGET
                  if (options.draggable !== false) {
                  mouse.target = $daddy.find(jQclass).has(this);
                  } else {
                  mouse.target = $self;
                  }

                  // ADD CLONE
                  mouse.clone = mouse.target.clone();
                  mouse.target.css({ visibility: 'hidden' }).addClass('active');
                  mouse.clone.addClass(cloneClass);
                  $daddy.append(mouse.clone);

                  // ADD PLACEHOLDER
                  var $placeholder = $('<div></div>');
                  mouse.placeholder = $placeholder;
                  mouse.placeholder.addClass(holderClass);
                  mouse.placeholder.css({
                  top: mouse.target.offset().top - $daddy.offset().top,
                  left: mouse.target.offset().left - $daddy.offset().left,
                  width: mouse.target.outerWidth() - 10,
                  height: mouse.target.outerHeight() - 10,
                  lineHeight: mouse.target.height() - 18 + 'px',
                  textAlign: 'center',
                  }).text(placeholder);

                  $daddy.append(mouse.placeholder);

                  // GET OFFSET FOR CLONE
                  var bLeft = Math.floor(parseFloat($daddy.css('border-left-width')));
                  var bTop = Math.floor(parseFloat($daddy.css('border-top-width')));
                  var difx = mouse.x - mouse.target.offset().left + $daddy.offset().left + bLeft;
                  var dify = mouse.y - mouse.target.offset().top + $daddy.offset().top + bTop;
                  mouse.cloneoffset.x = difx;
                  mouse.cloneoffset.y = dify;

                  // REMOVE THE CHILDREN DAD CLASS AND SET THE POSITION ON SCREEN
                  mouse.clone.removeClass(childrenClass).css({
                  position: 'absolute',
                  top: mouse.y - mouse.cloneoffset.y,
                  left: mouse.x - mouse.cloneoffset.x,
                  });

                  // UNABLE THE TEXT SELECTION AND SET THE GRAB CURSOR
                  $('html,body').addClass('dad-noSelect');
                }
            });

            $daddy.on('mouseenter touchenter', jQclass, function () {
                dadUpdate($(this));
            });
            });

            return this;
          };
      })(jQuery);   
    </script>
    <script type="text/javascript">
      $(function () {
          var myAction = {};

          var dom = {
            dad: $('#daddy'),
            delete: $('.js-delete')
          }

          $.extend(myAction, {
            initDad: function () {
            dom.dad.dad();
            },
            initEvent: function () {
            dom.delete.on('click', function () {
                var that = $(this);
                that.parent().remove();
            });            
            }
          });

          var init = function () {
            myAction.initDad();
            myAction.initEvent();
          }();
      });   
    </script>
</body>            
</html>不带删除功能:
<!DOCTYPE html>            
<html>            
<head>            
    <meta charset="UTF-8">            
    <title>拖拽插件jquery.dad.js</title>         
    <style type="text/css">
      .dad-noSelect,.dad-noSelect *{
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            cursor: -webkit-grabbing !important;
            cursor: -moz-grabbing !important;
      }

      .dad-container{
            position: relative;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
      }
      .dad-container::after{
            content: '';
            clear: both !important;
            display: block;
      }
      .dad-active .dad-draggable-area{
            cursor: -webkit-grab;
            cursor: -moz-grab;
      }
      .dad-draggable-area>*,.dad-draggable-area img{
            pointer-events: none;
      }
      .dads-children.active{
            pointer-events: none;
      }
      .dads-children-clone{
            opacity: 1;
            z-index: 9999;
            pointer-events: none;
      }
      .dads-children-placeholder{
            pointer-events: none;
            overflow: hidden;
            position: absolute !important;
            box-sizing: border-box;
            border:4px dashed #639BF6;
            margin:5px;
            text-align: center;
            color: #639BF6;
            font-weight: bold;
      }   
      .daddy>div {
            box-sizing: border-box;
            width: 20%;
            padding: 5px;
            float: left;
            display: block;
            position: relative;
      }
      .daddy>div>div {
            display: block;
            height: 120px;
            line-height: 120px;
            text-align: center;
            font-size: 30px;
            font-weight: bold;
            background: #639BF6;
            color: white;
            font-family: "Arial", sans-serif;
      }
    </style>
</head>            
<body>   
ccs文件和js文件可以去GitHub上下载,下载地址是:https://github.com/williammustaffa/jquery.dad.js
本实例是直接把源代码都复制过来了
    <div id="daddy" class="dad daddy">
      <div>
            <div>1</div>
      </div>
      <div>
            <div>2</div>
      </div>
      <div>
            <div>3</div>
      </div>
      <div>
            <div>4</div>
      </div>
      <div>
            <div>5</div>
      </div>
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <!-- <script src='jquery.dad.js'></script>    -->
    <script type="text/javascript">
      /*!
         * jquery.dad.js v1 (http://konsolestudio.com/dad)
         * Author William Lima
         */

      (function ($) {
          'use strict';
          var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

          $.fn.dad = function (opts) {
            var _this = this;

            var defaults = {
            target: '>div',
            draggable: false,
            placeholder: '',
            callback: false,
            containerClass: 'dad-container',
            childrenClass: 'dads-children',
            cloneClass: 'dads-children-clone',
            active: true,
            };

            var options = $.extend({}, defaults, opts);

            $(this).each(function () {
            var active = options.active;
            var $daddy = $(this);
            var childrenClass = options.childrenClass;
            var cloneClass = options.cloneClass;
            var jQclass = '.' + childrenClass;
            var $target = $daddy.find(options.target);
            var placeholder = options.placeholder;
            var callback = options.callback;
            var dragClass = 'dad-draggable-area';
            var holderClass = 'dads-children-placeholder';

            // HANDLE MOUSE
            var mouse = {
                x: 0,
                y: 0,
                target: false,
                clone: false,
                placeholder: false,
                cloneoffset: {
                  x: 0,
                  y: 0,
                },
                updatePosition: function (e) {
                  this.x = e.pageX;
                  this.y = e.pageY;
                },

                move: function (e) {
                  this.updatePosition(e);
                  if (this.clone !== false && _this.target !== false) {
                  this.clone.css({
                      left: this.x - this.cloneoffset.x,
                      top: this.y - this.cloneoffset.y,
                  });
                  }
                },
            };

            $(window).on('mousemove touchmove', function (e) {
                var ev = e;

                if (mouse.clone !== false && mouse.target !== false) e.preventDefault();

                if (supportsTouch && e.type == 'touchmove') {
                  ev = e.originalEvent.touches;
                  var mouseTarget = document.elementFromPoint(ev.clientX, ev.clientY);

                  $(mouseTarget).trigger('touchenter');
                }

                mouse.move(ev);
            });

            $daddy.addClass(options.containerClass);

            if (!$daddy.hasClass('dad-active') && active === true) {
                $daddy.addClass('dad-active');
            };

            _this.addDropzone = function (selector, func) {
                $(selector).on('mouseenter touchenter', function () {
                  if (mouse.target !== false) {
                  mouse.placeholder.css({ display: 'none' });
                  mouse.target.css({ display: 'none' });
                  $(this).addClass('active');
                  }
                }).on('mouseup touchend', function () {
                  if (mouse.target != false) {
                  mouse.placeholder.css({ display: 'block' });
                  mouse.target.css({ display: 'block' });
                  func(mouse.target);
                  dadEnd();
                  };

                  $(this).removeClass('active');
                }).on('mouseleave touchleave', function () {
                  if (mouse.target !== false) {
                  mouse.placeholder.css({ display: 'block' });
                  mouse.target.css({ display: 'block' });
                  }

                  $(this).removeClass('active');
                });
            };

            // GET POSITION FUNCTION
            _this.getPosition = function () {
                var positionArray = [];
                $(this).find(jQclass).each(function () {
                  positionArray[$(this).attr('data-dad-id')] = parseInt($(this).attr('data-dad-position'));
                });

                return positionArray;
            };

            _this.activate = function () {
                active = true;
                if (!$daddy.hasClass('dad-active')) {
                  $daddy.addClass('dad-active');
                }

                return _this;
            };

            // DEACTIVATE FUNCTION
            _this.deactivate = function () {
                active = false;
                $daddy.removeClass('dad-active');
                return _this;
            };

            // DEFAULT DROPPING
            $daddy.on('DOMNodeInserted', function (e) {
                var $thisTarget = $(e.target);
                if (!$thisTarget.hasClass(childrenClass) && !$thisTarget.hasClass(holderClass)) {
                  $thisTarget.addClass(childrenClass);
                }
            });

            $(document).on('mouseup touchend', function () {
                dadEnd();
            });

            // ORDER ELEMENTS
            var order = 1;
            $target.addClass(childrenClass).each(function () {
                if ($(this).data('dad-id') == undefined) {
                  $(this).attr('data-dad-id', order);
                }

                $(this).attr('data-dad-position', order);
                order++;
            });

            // CREATE REORDER FUNCTION
            function updatePosition(e) {
                var order = 1;
                e.find(jQclass).each(function () {
                  $(this).attr('data-dad-position', order);
                  order++;
                });
            }

            // END EVENT
            function dadEnd() {
                if (mouse.target != false &&mouse.clone != false) {
                  if (callback != false) {
                  callback(mouse.target);
                  }

                  var appear = mouse.target;
                  var desappear = mouse.clone;
                  var holder = mouse.placeholder;
                  var bLeft = 0;
                  var bTop = 0;

                  // Maybe we will use this in the future
                  //Math.floor(parseFloat($daddy.css('border-left-width')));
                  //Math.floor(parseFloat($daddy.css('border-top-width')));
                  if ($.contains($daddy, mouse.target)) {
                  mouse.clone.animate({
                      top: mouse.target.offset().top - $daddy.offset().top - bTop,
                      left: mouse.target.offset().left - $daddy.offset().left - bLeft,
                  }, 300, function () {
                      appear.css({
                        visibility: 'visible',
                      }).removeClass('active');
                      desappear.remove();
                  });
                  } else {
                  mouse.clone.fadeOut(300, function () {
                      desappear.remove();
                  });
                  }

                  holder.remove();
                  mouse.clone = false;
                  mouse.placeholder = false;
                  mouse.target = false;
                  updatePosition($daddy);
                }

                $('html, body').removeClass('dad-noSelect');
            }

            // UPDATE EVENT
            function dadUpdate(obj) {
                if (mouse.target !== false && mouse.clone !== false) {
                  var $origin = $('<span style="display:none"></span>');
                  var $newplace = $('<span style="display:none"></span>');

                  if (obj.prevAll().hasClass('active')) {
                  obj.after($newplace);
                  } else {
                  obj.before($newplace);
                  }

                  mouse.target.before($origin);
                  $newplace.before(mouse.target);

                  // UPDATE PLACEHOLDER
                  mouse.placeholder.css({
                  top: mouse.target.offset().top - $daddy.offset().top,
                  left: mouse.target.offset().left - $daddy.offset().left,
                  width: mouse.target.outerWidth() - 10,
                  height: mouse.target.outerHeight() - 10,
                  });

                  $origin.remove();
                  $newplace.remove();
                }
            }

            // GRABBING EVENT
            var jq = (options.draggable !== false) ? options.draggable : jQclass;
            $daddy.find(jq).addClass(dragClass);
            $daddy.on('mousedown touchstart', jq, function (e) {
                // For touchstart we must update "mouse" position
                if (e.type == 'touchstart') {
                  mouse.updatePosition(e.originalEvent.touches);
                }

                if (mouse.target == false && active == true && (e.which == 1 || e.type == 'touchstart')) {
                  var $self = $(this);

                  // GET TARGET
                  if (options.draggable !== false) {
                  mouse.target = $daddy.find(jQclass).has(this);
                  } else {
                  mouse.target = $self;
                  }

                  // ADD CLONE
                  mouse.clone = mouse.target.clone();
                  mouse.target.css({ visibility: 'hidden' }).addClass('active');
                  mouse.clone.addClass(cloneClass);
                  $daddy.append(mouse.clone);

                  // ADD PLACEHOLDER
                  var $placeholder = $('<div></div>');
                  mouse.placeholder = $placeholder;
                  mouse.placeholder.addClass(holderClass);
                  mouse.placeholder.css({
                  top: mouse.target.offset().top - $daddy.offset().top,
                  left: mouse.target.offset().left - $daddy.offset().left,
                  width: mouse.target.outerWidth() - 10,
                  height: mouse.target.outerHeight() - 10,
                  lineHeight: mouse.target.height() - 18 + 'px',
                  textAlign: 'center',
                  }).text(placeholder);

                  $daddy.append(mouse.placeholder);

                  // GET OFFSET FOR CLONE
                  var bLeft = Math.floor(parseFloat($daddy.css('border-left-width')));
                  var bTop = Math.floor(parseFloat($daddy.css('border-top-width')));
                  var difx = mouse.x - mouse.target.offset().left + $daddy.offset().left + bLeft;
                  var dify = mouse.y - mouse.target.offset().top + $daddy.offset().top + bTop;
                  mouse.cloneoffset.x = difx;
                  mouse.cloneoffset.y = dify;

                  // REMOVE THE CHILDREN DAD CLASS AND SET THE POSITION ON SCREEN
                  mouse.clone.removeClass(childrenClass).css({
                  position: 'absolute',
                  top: mouse.y - mouse.cloneoffset.y,
                  left: mouse.x - mouse.cloneoffset.x,
                  });

                  // UNABLE THE TEXT SELECTION AND SET THE GRAB CURSOR
                  $('html,body').addClass('dad-noSelect');
                }
            });

            $daddy.on('mouseenter touchenter', jQclass, function () {
                dadUpdate($(this));
            });
            });

            return this;
          };
      })(jQuery);   
    </script>
    <script type="text/javascript">
      $(function () {
          //dad simple demo
          $('.dad').dad();
      });   
    </script>
</body>            
</html>




文档来源:51CTO技术博客https://blog.51cto.com/u_15315190/3202261
页: [1]
查看完整版本: 拖拽插件jquery.dad.js