带删除功能:
<!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;
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,
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,
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;
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,
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,
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>
备注:欢迎加入web前端求职招聘qq群:668352707