自己写的一个dragsort拖动排序插件
2026-04-29 17:56:22
234
分类:js插件
拖动排序插件Nestable很好用,但是我要把table排序怎么不行呢,我也不想改变我页面的结构,所以自己写了一个拖动排序插件,主要针对table吧。
示例效果

代码
/*
* 作者:黄飞
* 时间:2018.3.24
* 说明:对表格的拖动排序操作,兼容移动端
* 使用方法:
* var drag = new dragsort('#table tbody tr');
* drag.init();// 注册事件
* drag.off(); // 注销事件
* 注:写得比较简单,只能适应于对应的环境,如有bug或设计缺陷请联系我
*/
(function ($, window) {
"use strict";
var dragEvents = {}; //兼容手机端
if ('ontouchstart' in document.documentElement) {
dragEvents = {START: 'touchstart', MOVE: 'touchmove', END: 'touchend'}
} else {
dragEvents = {START: 'mousedown', MOVE: 'mousemove', END: 'mouseup'}
}
var Dragsort = function (element, options) {
var defaults = {
threshold: 5, //拖动距离
};
this.dragging = false; //拖动中
this.allEle = element;
this.$element; //拖动元素
this.originalClient = {X: 0, Y: 0}; //拖动起点x
this.originalPosition; //拖动元素原始位置
this.$clone; //克隆元素
this.settins = $.extend({}, defaults, options);
}
Dragsort.prototype = {
constructor: Dragsort,
//注册事件
init: function () {
var self = this;
$(self.allEle).each(function () {
if (self.settins.dragSelector) {
//拖动元素
$(this).on(dragEvents.START, {
self: self,
dragElement: self.settins.dragSelector
}, self.dragStartHandler);
}
else {
$(this).on(dragEvents.START, {self: self, dragElement: this}, self.dragStartHandler);
}
});
},
//开始拖动
dragStartHandler: function (event) {
document.onselectstart = function () {
return false;
};
var $element = $(event.data.dragElement);
var self = event.data.self;
self.$element = $element;
self.originalClient.X = event.clientX || event.originalEvent.touches[0].clientX;
self.originalClient.Y = event.clientY || event.originalEvent.touches[0].clientY;
self.originalPosition = self.$element.position();
$(document).on(dragEvents.MOVE, {self: self}, self.dragMoveHandler).on(dragEvents.END, {self: self}, self.dragEndHandler);
},
//拖动元素
dragMoveHandler: function (event) {
var self = event.data.self;
var dragDistanceX = (event.clientX || event.originalEvent.touches[0].clientX) - self.originalClient.X,
dragDistanceY = (event.clientY || event.originalEvent.touches[0].clientY) - self.originalClient.Y;
if (self.dragging) {
self.$clone.css({
left: self.originalPosition.left + dragDistanceX,
top: self.originalPosition.top + dragDistanceY
});
self.shiftHoveredElement(self.$clone, self.$element);
}
else if (Math.abs(dragDistanceX) > self.settins.threshold || Math.abs(dragDistanceY) > self.settins.threshold) {
self.$clone = self.clone(self.$element);
self.$element.parent().append(self.$clone);
self.$element.css({visibility: 'hidden', cursor: 'move'});
self.dragging = true;
}
},
//拖动结束
dragEndHandler: function (event) {
var self = event.data.self;
self.dragging = false;
self.$clone.remove();
self.$element.css({visibility: 'visible', cursor: 'default'});
$(document).off(dragEvents.MOVE).off(dragEvents.END);
},
//克隆元素
clone: function () {
var $clone = this.$element.clone();
$clone.css({
// display: 'table', //常用的table
position: 'absolute',
width: this.$element.width(),
height: this.$element.height(),
top: this.originalPosition.top,
left: this.originalPosition.left,
'z-index': 100000,
border: '2px solid red'
});
this.$element.find('td').each(function (index, item) {
$clone.find('td').eq(index).css({width: item.clientWidth + 'px'});
});
return $clone;
},
//拖动克隆元素时悬浮在某个元素上
shiftHoveredElement: function ($clone, $dragElement) {
var $movableElements = $(this.allEle);
var hoveredElement = this.getHoveredElement($clone, $dragElement, $movableElements);
var hoveredElementIndex = $movableElements.index(hoveredElement);
var dragElementIndex = $movableElements.index($dragElement);
if (hoveredElementIndex < dragElementIndex) {
$(hoveredElement).before($dragElement);
} else {
$(hoveredElement).after($dragElement);
}
},
//获取克隆元素悬浮在某个元素上的元素
getHoveredElement: function ($clone, $dragElement, $movableElements) {
for (var i = 0; i < $movableElements.length; i++) {
var $currentElement = $movableElements.eq(i);
if ($currentElement[0] == this.$element[0]) {
continue;
}
var eleTop = $currentElement.position().top,
eleLeft = $currentElement.position().left,
eleRight = eleLeft + $currentElement.width(),
eleBottom = eleTop + $currentElement.height();
var overlappingY = $clone.position().top > eleTop && $clone.position().top < eleBottom;
if (overlappingY) {
return $currentElement[0];
}
}
},
//注销事件
off: function () {
$(this.allEle).each(function () {
$(this).off(dragEvents.START);
});
}
}
window.dragsort = Dragsort;
})(window.jQuery, window);