拖拽插件jquery.dad.js

 

 

 带删除功能:javascript

<!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[0];
                  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[0], mouse.target[0])) {
                    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[0]);
                }
 
                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>

 不带删除功能:css

<!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[0];
                  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[0], mouse.target[0])) {
                    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[0]);
                }

                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>