dragsort html拖拽排序 的应用

drag-sorts react-native平台实现的拖拽组件,简单已用,可以结合多种动画实现!!组件化模块化!!!!!!! 立即下载
/**
 *
 *
 * 设置参数的说明:
 * drag:开始拖拽的回调
 * beforeExchange: 当被拖拽元素, 和相邻的元素交换位置前的回调方法,如果回调方法返回 false 那么会阻止位置的交换, 回调的入参(exchangeItem(将要交换位置的元素))
 * afterExchange: 当被拖拽元素, 和相邻的元素交换位置后的回调方法, 回调的入参(与拖拽元素交换位置的那个元素)
 * drop: 结束拖拽的回调
 * selector: 拖拽目标的选择器
 * scrollSpeed:如果被拖拽的元素的容器有滚动条,这个参数可以用来控制滚动的速度
 * debounce: 防抖参数设置, 单位ms, 识别点击动作和开始拖拽之间的抖动,避免误判
 * dragSwitch: 是否启用拖拽开关控制拖拽的开启关闭(默认true), true 用开关控制拖拽的开启于关闭分; false 直接开启拖拽功能
 * switchPosition: 如果启用了拖拽开关, 此属性来设置开关的位置(如果不设置默认开关将添加到启用拖拽功能元素的右上角), 这个值为目标元素的ID, 如
 *                      有元素<div id="switch"></div>, switchPosition: 'switch'. 那么开关图标将浮动在此div的右上角
 *                      注意: 这个元素不能有overflow: hidden;属性, 因为开关会作为子元素插入到这个元素中而, 所以不能浮动出去, 会被hidden掉
 * relation: 需要级联目前元素的选择器.  当前启用拖拽功能的元素可能需要联动另一个元素时!比如数据区有固定列功能,是两个table组成的,那么设置好选择器当拖拽table1时就可以联动table2了
 * placeHolderStyle: 占位元素的样式
 * floatStyle: 被拖拽的元素浮动起来后, 可以额外添加样式
 */
(function ($, w) {//$代替jQuery,w代替window
    var defaults = {
    		//$.noop() 函数是一个空函数。
    		//注意:此方法不接受任何参数。比如当插件提供了一个可选的回调函数接口,那么如果调用的时候没有传递这个回调函数,就用$.noop来代替执行。
        drag: $.noop,
        beforeExchange: $.noop,
        afterExchange: $.noop,
        drop: $.noop,
        selector: 'tr',
        scrollSpeed: '',
        debounce: 100,//ms
        dragSwitch: true,
        switchPosition: '',
        relation: '',
        placeHolderStyle: {
            //占位元素的样式
        },
        floatStyle: {
            'position': 'fixed'
        }
    };
//jQuery.fn.extend(object); 对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。
    $.fn.dragSort = function (options) {
        var $doc = $(w.document);
        var settings = $.extend(true, {}, defaults, options);//jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象。
        
        return this.each(function () {
            //缓存当前DOM为jQuery对象
            var container = $(this);
            //联动元素
            var $relation = $(settings.relation);
            //为所选元素的右上角追加一个切换是否开启拖拽的开关
            var turnOnDrag = true;//是否启用拖拽的状态标记
            if (settings.dragSwitch) {
                turnOnDrag = false;
                //开关默认附着在container上
                var elementForSwitch = container;
                //如果指定了开关的位置
                if (settings.switchPosition && $("#"+ settings.switchPosition).length > 0) {
                    elementForSwitch = $("#"+ settings.switchPosition);
                }
                if (elementForSwitch.css("position") == "static") {
                    elementForSwitch.css("position", "relative");
                }
                var timer;
                var dragSwitchId = Math.random().toString().substring(2);//获取0-1之间的随机数,去掉0和.
                var stateIconId = dragSwitchId + "stateIcon";
                container.mouseover(function() {
                    clearTimeout(timer);
                    var width = elementForSwitch.width();
                    var $dragSwitch = $("#" + dragSwitchId);
                    if ($dragSwitch.length == 0) {
                        $("<div id='" + dragSwitchId + "' class='dragSwitch'><span id='" + stateIconId + "' class='icon-move'></span></div>").css({
                            top: -18,
                            left: width - 18,
                        }).appendTo(elementForSwitch);
                        $("#" + dragSwitchId).click(function() {
                            if (turnOnDrag) {
                                turnOnDrag = false;
                                $("#" + stateIconId).attr('class','icon-move');
                            } else {
                                turnOnDrag = true;
                                $("#" + stateIconId).attr('class','icon-ban-circle');
                            }
                            return false;
                        });
                    } else {
                        $dragSwitch.show();
                    }
                }).mouseout(function() {
                    timer = setTimeout(function(){$("#" + dragSwitchId).hide()}, 3000);//这个3000表示鼠标移除事件响应区3000ms后,开关消失
                });
            }
            //on() 方法在被选元素及子元素上添加一个或多个事件处理程序。
            container.on('mousedown.dragSort', settings.selector, function (e) {
                if (!turnOnDrag) {
                    return;
                }
                // 只处理鼠标左键的事件 1是鼠标左键的代码
                if (e.which != 1) {
                    return;
                }
                // 防止表单类元素无法编辑
                var $eventTarget = $(e.target);
                if (($eventTarget.is('input')
                    || $eventTarget.is('select')
                    || $eventTarget.is('textarea')
                    || $eventTarget.is('a')
                    || $(e.target).prop('contenteditable') == true)
                    && $eventTarget.prop('readonly') == false) {
                	//prop() 方法设置或返回被选元素的属性和值。
                    return;
                }
                var startTime = $.now();//jQuery.now()方法.返回当前时间的Unix时间戳


                //被拖拽元素
                var $dragItem = $(this);
                //元素标签
                var tagName = $dragItem.prop('tagName');
                //在容器中找到与被拖拽元素相同类型下以[id^="'+TriangleDefinition.HTML_ID_PREFIX_TR_INDEX+'"]最小的索引, 因table翻页的存在不一定最小的就是1
                //这个求最小索引的动作, 每次拖拽都会运算一次, 如果发现影响效率可以将当前运算提到上一层
                var minimum = null;
                container.find(tagName + " [id^='" + TriangleDefinition.HTML_ID_PREFIX_TR_INDEX +"']").each(function(){
                    var index = $(this).text() || $(this).val();
                    if(index == 0){
                    	index = 1;
                    }
                    if (minimum == null) {
                        minimum = index;
                    } else if (index < minimum) {
                        minimum = index;
                    }
                });


                //被拖拽的元素在容器中的索引
                var dragItemIndex = $dragItem.index();
                // 元素的位置,相对于document
                var offset = $dragItem.offset();


                // 鼠标指针的位置,相对document
                var mouseX = e.pageX;
                var mouseY = e.pageY;


                var distanceX = mouseX - offset.left;
                var distanceY = mouseY - offset.top;


                var dragItemHeight = $dragItem.outerHeight();//outerHeight() 方法返回第一个匹配元素的外部高度。
                var dragItemWidth = $dragItem.outerWidth();


                //备份拖拽元素的原内联样式
                var originalStyle = $dragItem.attr("style");
                // 6是让占位元素的高度高于浮动元素, 以突出当前浮动元素
                var placeHolderEle = $dragItem.clone().empty()
                    .removeAttr("style")
                    .css(settings.placeHolderStyle)
                    .css('height', dragItemHeight + 6)
                    .css('width', dragItemWidth);


                var hasPlaceHolderEle = false;


                var containerOuterHeight = container.outerHeight();


                // 滚动速度
                var scrollSpeed = settings.scrollSpeed || dragItemHeight;
                var maxSpeed = scrollSpeed * 3;


                // TODO:防抖处理, 过滤click事件时产生的mousedown
                //call方法:                 语法:call(thisObj,Object)                定义:调用一个对象的一个方法,以另一个对象替换当前对象。
                //drag,是用于写回调的方法名:这个方法需要调用这个代码的地方写
                if (settings.drag.call($dragItem) === false ) {
                    return;
                }
                $doc.on('mousemove.dragSort', function (e) {
                    // 简单的防抖处理, 单击时不明原因会产生mousemove事件
                    if ($.now() - startTime < settings.debounce) {
                        return;
                    }
                    // TODO:对mousemove事件的节流处理
                    //startTime = $.now();


                    // 插入占位元素并浮动拖拽元素
                    if (!hasPlaceHolderEle) {
                        $dragItem.children().each(function() {
                            var style = $(this).attr("style");
                            var hasWidthStyle = false;
                            if (style) {
                                var styleArray = style.split(";");
                                for (var i in styleArray) {
                                    var kv = styleArray[i];
                                    if (kv) {
                                        var k = kv.split(":")[0].trim();
                                        var v = kv.split(":")[1].trim();
                                        if (k == "width") {
                                            $(this).width(v);
                                            hasWidthStyle = true;
                                        }
                                    }
                                }
                            }
                            if (!hasWidthStyle) {
                                $(this).width($(this).width());
                            }
                        });
                        //before() 方法在被选元素前插入指定的内容。
                        $dragItem.before(placeHolderEle).css(settings.floatStyle);
                        hasPlaceHolderEle = true;
                    }
                    var mouseX = e.pageX;
                    var mouseY = e.pageY;


                    var left = mouseX - distanceX;
                    var top = mouseY - distanceY;


                    // 设置拖拽元素悬浮位置
                    $dragItem.css({
                        left: left - $doc.scrollLeft(),//返回当前视图中的实际元素的左边缘和左边缘之间的距离
                        top: top - $doc.scrollTop()//返回当前视图中的实际元素的顶部边缘和顶部边缘之间的距离
                    });


                    var prev = placeHolderEle.prev();//prev() 获得匹配元素集合中每个元素紧邻的前一个同胞元素,通过选择器进行筛选是可选的。
                    var next = placeHolderEle.next();
                    next = next.is($dragItem) ? next.next() : next;


                    // 调用回调,并根据回调返回结果判断是否于临界dom交换位置
                    if (prev.length && top < prev.offset().top + prev.outerHeight() / 2) {
                        if (!(settings.beforeExchange.call($dragItem, prev) === false)) {
                            placeHolderEle.after(prev);
                            settings.afterExchange.call($dragItem, prev);
                        }
                    } else if (next.length && top + dragItemHeight > next.offset().top + next.outerHeight() / 2) {
                        if (!(settings.beforeExchange.call($dragItem, next) === false)) {
                            placeHolderEle.before(next);
                            settings.afterExchange.call($dragItem, next);
                        }
                    }


                    // 处理container纵向滚动条,container 可能是带着滚动条的元素
                    var scrollTop = container.parent('div').scrollTop();
                    var offsetTop = container.offset().top;
                    var scrollVal;


                    /**containerOuterHeight   左表的外部高度   ------ 应该改成滚动区域的高度
                     * dragItemHeight      拖拽目标的外部高度
                     * scrollSpeed  在这里= 拖拽目标的外部高度
                     * maxSpeed     拖拽目标的外部高度*3
                     * offsetTop    左表的top属性
                     * top     光标的位置
                     * 
                    */
                     var scorllHeight = container.parent("div").height();
                    // 向上滚动
                    if (top < offsetTop) {
                        scrollSpeed = ++scrollSpeed > maxSpeed ? maxSpeed : scrollSpeed;
                        scrollVal = scrollTop - scrollSpeed;
                        // 向下滚动
                    } else if (top + dragItemHeight - offsetTop > scorllHeight) {
                        scrollSpeed = ++scrollSpeed > maxSpeed ? maxSpeed : scrollSpeed;
                        scrollVal = scrollTop + scrollSpeed;
                    }


                    container.parent('div').scrollTop(scrollVal);
                })
                .on('mouseup.dragSort', function () {
                    $doc.off('mousemove.dragSort mouseup.dragSort');
                    if (hasPlaceHolderEle) {
                        $dragItem = originalStyle == undefined ? $dragItem.removeAttr('style') : $dragItem.attr('style', originalStyle);
                        //新位置的索引     index() 方法返回指定元素相对于其他指定元素的 index 位置。
                        var placeHolderEleIndex = placeHolderEle.index();
                        //拖拽区域的滚动Y值
                        var placeHolderEleScrollTop = container.parent('div').scrollTop();
                        //replaceWith() 方法用指定的 HTML 内容或元素替换被选元素。
                        placeHolderEle.replaceWith($dragItem);
                        //联动关联的元素
                        $relation.each(function() {
                            var $relationEle = $(this);
                            if (placeHolderEleIndex > dragItemIndex) {
                                //被拖拽元素向下移动了
                                $relationEle.find(tagName+":eq("+ placeHolderEleIndex +")").after($relationEle.find(tagName+":eq("+ dragItemIndex +")"));
                            } else if (placeHolderEleIndex < dragItemIndex) {
                                //被拖拽元素向上移动了
                                $relationEle.find(tagName+":eq("+ placeHolderEleIndex +")").before($relationEle.find(tagName+":eq("+ dragItemIndex +")"));
                            }
                            
                            //处理关联的无素的滚动条
                            $relationEle.parent('div').scrollTop(placeHolderEleScrollTop);
                        });
                        //如果有需要处理的索引则处理索引(id^=TriangleDefinition.HTML_ID_PREFIX_TR_INDEX)的元素, 目前只考虑了,
                        // 只有一列数据有这个ID的情况, 如果有多列的数据都有这个ID那么会计算错误
                        container.find(tagName + " [id^='" + TriangleDefinition.HTML_ID_PREFIX_TR_INDEX +"']").each(function(){
                            var tag = $(this).prop('tagName').toLowerCase();


                            if (tag == "input") {
                                $(this).val(minimum++);
                            } else {
                                $(this).text(minimum++);
                            }
                        });
                        //回调
                        settings.drop.call($dragItem);
                    }
                });
                return false;
            });
        });
    };
})(jQuery, window);
// jquery.dragsort.js  原码
// jQuery List DragSort v0.5.2
// Website: http://dragsort.codeplex.com/
// License: http://dragsort.codeplex.com/license

(function($) {

	$.fn.dragsort = function(options) {
		if (options == "destroy") {
			$(this.selector).trigger("dragsort-uninit");
			return;
		}

		var opts = $.extend({}, $.fn.dragsort.defaults, options);
		var lists = [];
		var list = null, lastPos = null;

		this.each(function(i, cont) {

			//if list container is table, the browser automatically wraps rows in tbody if not specified so change list container to tbody so that children returns rows as user expected
			if ($(cont).is("table") && $(cont).children().size() == 1 && $(cont).children().is("tbody"))
				cont = $(cont).children().get(0);

			var newList = {
				draggedItem: null,
				placeHolderItem: null,
				pos: null,
				offset: null,
				offsetLimit: null,
				scroll: null,
				container: cont,

				init: function() {
					//set options to default values if not set
					opts.tagName = $(this.container).children().size() == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase();
					if (opts.itemSelector == "")
						opts.itemSelector = opts.tagName;
					if (opts.dragSelector == "")
						opts.dragSelector = opts.tagName;
					if (opts.placeHolderTemplate == "")
						opts.placeHolderTemplate = "<" + opts.tagName + "> </" + opts.tagName + ">";

					//listidx allows reference back to correct list variable instance
					$(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
					this.styleDragHandlers(true);
				},

				uninit: function() {
					var list = lists[$(this).attr("data-listidx")];
					$(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
					list.styleDragHandlers(false);
				},

				getItems: function() {
					return $(this.container).children(opts.itemSelector);
				},

				styleDragHandlers: function(cursor) {
					this.getItems().map(function() { return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get(); }).css("cursor", cursor ? "pointer" : "");
				},

				grabItem: function(e) {
					var list = lists[$(this).attr("data-listidx")];
					var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
					var insideMoveableItem = list.getItems().filter(function() { return this == item; }).size() > 0;

					//if not left click or if clicked on excluded element (e.g. text box) or not a moveable list item return
					if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).size() > 0 || !insideMoveableItem)
						return;

					//prevents selection, stops issue on Fx where dragging hyperlink doesn't work and on IE where it triggers mousemove even though mouse hasn't moved,
					//does also stop being able to click text boxes hence dragging on text boxes by default is disabled in dragSelectorExclude
					e.preventDefault();

					//change cursor to move while dragging
					var dragHandle = e.target;
					while (!$(dragHandle).is(opts.dragSelector)) {
						if (dragHandle == this) return;
						dragHandle = dragHandle.parentNode;
					}
					$(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
					$(dragHandle).css("cursor", "move");

					//on mousedown wait for movement of mouse before triggering dragsort script (dragStart) to allow clicking of hyperlinks to work
					var listElem = this;
					var trigger = function() {
						list.dragStart.call(listElem, e);
						$(list.container).unbind("mousemove", trigger);
					};
					$(list.container).mousemove(trigger).mouseup(function() { $(list.container).unbind("mousemove", trigger); $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor")); });
				},

				dragStart: function(e) {
					if (list != null && list.draggedItem != null)
						list.dropItem();

					list = lists[$(this).attr("data-listidx")];
					list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName);

					//record current position so on dragend we know if the dragged item changed position or not, not using getItems to allow dragsort to restore dragged item to original location in relation to fixed items
					list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));

					//calculate mouse offset relative to draggedItem
					var mt = parseInt(list.draggedItem.css("marginTop"));
					var ml = parseInt(list.draggedItem.css("marginLeft"));
					list.offset = list.draggedItem.offset();
					list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
					list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;

					//calculate box the dragged item can't be dragged outside of
					if (!opts.dragBetween) {
						var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + list.getItems().size() * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight();
						list.offsetLimit = $(list.container).offset();
						list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
						list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
					}

					//create placeholder item
					var h = list.draggedItem.height();
					var w = list.draggedItem.width();
					if (opts.tagName == "tr") {
						list.draggedItem.children().each(function() { $(this).width($(this).width()); });
						list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
						list.draggedItem.after(list.placeHolderItem);
						list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html(" "); });
					} else {
						list.draggedItem.after(opts.placeHolderTemplate);
						list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeholder", true);
					}

					if (opts.tagName == "td") {
						var listTable = list.draggedItem.closest("table").get(0);
						$("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
					}

					//style draggedItem while dragging
					var orig = list.draggedItem.attr("style");
					list.draggedItem.attr("data-origstyle", orig ? orig : "");
					list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w });

					//auto-scroll setup
					list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() };
					list.scroll.scrollY = window.setInterval(function() {
						if (opts.scrollContainer != window) {
							$(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
							return;
						}
						var t = $(opts.scrollContainer).scrollTop();
						if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
							$(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
							list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
						}
					}, 10);
					list.scroll.scrollX = window.setInterval(function() {
						if (opts.scrollContainer != window) {
							$(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
							return;
						}
						var l = $(opts.scrollContainer).scrollLeft();
						if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
							$(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
							list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
						}
					}, 10);

					//misc
					$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
					list.setPos(e.pageX, e.pageY);
					$(document).bind("mousemove", list.swapItems);
					$(document).bind("mouseup", list.dropItem);
					if (opts.scrollContainer != window)
						$(window).bind("wheel", list.wheel);
				},

				//set position of draggedItem
				setPos: function(x, y) { 
					//remove mouse offset so mouse cursor remains in same place on draggedItem instead of top left corner
					var top = y - this.offset.top;
					var left = x - this.offset.left;

					//limit top, left to within box draggedItem can't be dragged outside of
					if (!opts.dragBetween) {
						top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
						left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
					}

					//adjust top & left calculations to parent offset
					var parent = this.draggedItem.offsetParent().not("body").offset(); //offsetParent returns body even when it's static, if not static offset is only factoring margin
					if (parent != null) {
						top -= parent.top;
						left -= parent.left;
					}

					//set x or y auto-scroll amount
					if (opts.scrollContainer == window) {
						y -= $(window).scrollTop();
						x -= $(window).scrollLeft();
						y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
						x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
					} else {
						var cont = $(opts.scrollContainer);
						var offset = cont.offset();
						y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
						x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
					}
					
					list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
					list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);

					//move draggedItem to new mouse cursor location
					this.draggedItem.css({ top: top, left: left });
				},

				//if scroll container is a div allow mouse wheel to scroll div instead of window when mouse is hovering over
				wheel: function(e) {
					if (list && opts.scrollContainer != window) {
						var cont = $(opts.scrollContainer);
						var offset = cont.offset();
						e = e.originalEvent;
						if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
							var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
							cont.scrollTop(cont.scrollTop() + deltaY);
							e.preventDefault();
						}
					}
				},

				//build a table recording all the positions of the moveable list items
				buildPositionTable: function() {
					var pos = [];
					this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function(i) {
						var loc = $(this).offset();
						loc.right = loc.left + $(this).outerWidth();
						loc.bottom = loc.top + $(this).outerHeight();
						loc.elm = this;
						pos[i] = loc;
					});
					this.pos = pos;
				},

				dropItem: function() {
					if (list.draggedItem == null)
						return;

					//list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower
					//list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower)
					var orig = list.draggedItem.attr("data-origstyle");
					list.draggedItem.attr("style", orig);
					if (orig == "")
						list.draggedItem.removeAttr("style");
					list.draggedItem.removeAttr("data-origstyle");

					list.styleDragHandlers(true);

					list.placeHolderItem.before(list.draggedItem);
					list.placeHolderItem.remove();

					$("[data-droptarget], .dragSortItem").remove();

					window.clearInterval(list.scroll.scrollY);
					window.clearInterval(list.scroll.scrollX);

					//if position changed call dragEnd
					if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
						if (opts.dragEnd.apply(list.draggedItem) == false) { //if dragEnd returns false revert order
							var pos = list.draggedItem.attr("data-origpos").split('-');
							var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
							if (nextItem.size() > 0)
								nextItem.before(list.draggedItem);
							else if (pos[1] == 0) //was the only item in list
								$(lists[pos[0]].container).prepend(list.draggedItem);
							else //was the last item in list
								$(lists[pos[0]].container).append(list.draggedItem);
						}
					list.draggedItem.removeAttr("data-origpos");

					list.draggedItem = null;
					$(document).unbind("mousemove", list.swapItems);
					$(document).unbind("mouseup", list.dropItem);
					if (opts.scrollContainer != window)
						$(window).unbind("wheel", list.wheel);
					return false;
				},

				//swap the draggedItem (represented visually by placeholder) with the list item the it has been dragged on top of
				swapItems: function(e) {
					if (list.draggedItem == null)
						return false;

					//move draggedItem to mouse location
					list.setPos(e.pageX, e.pageY);

					//retrieve list and item position mouse cursor is over
					var ei = list.findPos(e.pageX, e.pageY);
					var nlist = list;
					for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
						ei = lists[i].findPos(e.pageX, e.pageY);
						nlist = lists[i];
					}

					//if not over another moveable list item return
					if (ei == -1)
						return false;

					//save fixed items locations
					var children = function() { return $(nlist.container).children().not(nlist.draggedItem); };
					var fixed = children().not(opts.itemSelector).each(function(i) { this.idx = children().index(this); });

					//if moving draggedItem up or left place placeHolder before list item the dragged item is hovering over otherwise place it after
					if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
						$(nlist.pos[ei].elm).before(list.placeHolderItem);
					else
						$(nlist.pos[ei].elm).after(list.placeHolderItem);

					//restore fixed items location
					fixed.each(function() {
						var elm = children().eq(this.idx).get(0);
						if (this != elm && children().index(this) < this.idx)
							$(this).insertAfter(elm);
						else if (this != elm)
							$(this).insertBefore(elm);
					});

					//misc
					$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
					lastPos = list.draggedItem.offset();
					return false;
				},

				//returns the index of the list item the mouse is over
				findPos: function(x, y) {
					for (var i = 0; i < this.pos.length; i++) {
						if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
							return i;
					}
					return -1;
				},

				//create drop targets which are placeholders at the end of other lists to allow dragging straight to the last position
				createDropTargets: function() {
					if (!opts.dragBetween)
						return;

					$(lists).each(function() {
						var ph = $(this.container).find("[data-placeholder]");
						var dt = $(this.container).find("[data-droptarget]");
						if (ph.size() > 0 && dt.size() > 0)
							dt.remove();
						else if (ph.size() == 0 && dt.size() == 0) {
							if (opts.tagName == "td")
								$(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
							else
								//list.placeHolderItem.clone().removeAttr("data-placeholder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8)
								$(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));
							
							list.placeHolderItem.attr("data-placeholder", true);
						}
					});
				}
			};

			newList.init();
			lists.push(newList);
		});

		return this;
	};

	$.fn.dragsort.defaults = {
		itemSelector: "",
		dragSelector: "",
		dragSelectorExclude: "input, textarea",
		dragEnd: function() { },
		dragBetween: false,
		placeHolderTemplate: "",
		scrollContainer: window,
		scrollSpeed: 5
	};

})(jQuery);



【Vite+Vue3+TS】基于Vite+Vue3+TypeScript+ESLint+Prettier+Stylelint搭建项目(亲测超详细) 结合了很多项目和文章,总结一篇项目构建的笔记。 温馨提示:文章末尾记录了我在搭建项目过程中,遇到的一些问题和解决办法 ~ 阅读详情

相关推荐

EverOS:为AI智能体构建长期记忆系统的完整指南

长期记忆是AI智能体实现持续学习和自我演进的核心能力,它通过结构化存储和关联检索历史交互信息,使智能体能够跨越单次对话的局限。其技术原理通常涉及向量数据库、记忆提取算法和知识图谱等组件,用于对非结构化对话内容进行编码、组织和索引。这一能力的技术价值在于显著提升了智能体的个性化服务水平、任务完成连贯性以及从经验中学习的能力,是实现真正“智能”伙伴的关键。在应用场景上,长期记忆系统广泛应用于个性化聊天伴侣、持续学习的编程助手、游戏NPC角色塑造以及客户服务机器人等领域。本文以EverOS为例,深入解析了其提供的

weixin_28679635的博客 450

探秘DragSort:一款高效易用的拖拽排序库

探秘DragSort:一款高效易用的拖拽排序库 去发现同类优质开源项目:https://gitcode.com/ 是一个轻量级、高性能的JavaScript库,专为Web应用中的列表元素提供了流畅的拖放排序功能。如果你在开发过程中需要实现用户友好的交互体验,尤其是涉及动态调整列表顺序的场景,那么DragSort无疑是一个值得考虑的选择。 技术解析 DragSort的核心在于其对HTML5 drag...

gitblog_00052的博客 639

实现飞书机器人推送消息到指定群组或者用户

飞书是一个集成了聊天、协作和办公功能的企业级平台,广泛应用于企业内部沟通和协作。飞书机器人(Feishu Bot)是一种强大的工具,允许开发者通过编程接口与飞书进行互动,从而实现自动化消息推送和任务管理。本文将详细介绍如何通过飞书机器人推送消息给指定的人或者群组,帮助您快速上手。

qq_41898196的博客 5872

推荐一款神奇的开源项目:DragSort - 拖拽排序库

推荐一款神奇的开源项目:DragSort - 拖拽排序库 在我们的日常开发中,无论是Web应用还是移动应用,经常需要实现一些交互性强、用户体验好的排序功能。今天,我要向大家推荐一个强大的开源项目——,它是一款为Android平台设计的拖拽排序库,能够让你轻松实现手指滑动即可调整列表顺序的功能。 项目简介 DragSort是一个由@kevenfeng维护的Android库,它的主要目标是提供一种简单...

gitblog_00068的博客 543

Zynq裸机调试RTL8211FS网卡踩坑记:从ping不通到完美兼容的完整代码修改

本文详细记录了在Zynq平台上使用Xilinx SDK(XSDK)调试RTL8211FS网卡的完整过程,从最初的ping不通问题到最终实现完美兼容的解决方案。通过分析PHY芯片的寄存器配置差异,提供了关键代码修改和调试技巧,帮助开发者快速解决类似问题。

weixin_42550597的博客 422

OpenClaw 从新手到中级完整教程【完整 持续更新版】

OpenClaw(曾用名 ClawdBot/Moltbot)是 2026 年最火的开源 AI Agent 项目,GitHub 已获得超过 68,000 星标。它不是普通的聊天机器人,而是一个真正能够执行任务的个人 AI 助理。

FeelTouch Labs 3116

特别好用的拖拽插件DragSort

参考:https://www.cnblogs.com/always-online/p/5160475.html

漫天随飞雪的博客 1183

Android Keymaster- 设备集成笔记 嵌入式

本文介绍了 Android Keymaster 的原理、使用方法和示例源代码。Android Keymaster 是一个重要的安全组件,为开发者提供了加密和解密功能,用于保护设备上存储的敏感数据。Android Keymaster 是 Android 系统的一个安全组件,用于保护设备上存储的敏感数据。Keymaster 使用基于硬件的密钥存储,同时提供了一组 API,让开发者可以在应用程序中使用这些加密功能。在嵌入式设备中,Android Keymaster 是一个重要的组件,用于提供加密和解密功能。

LrFortran的博客 671

dragsort 拖拽插件,点击事件不生效问题解决方法

项目需要上传多张图片,并给图片排序,就只用了dragsort插件,但是之前支持的点击图片删除功能不生效了,一开始试了很多方法,后面才知道点击事件被当成了移动事件 下面是一开始加的代码,支持图片移动 $("body .demo").dragsort({ dragSelector: "li", dragBetween: true, dragEnd: function() {} }); 下面是添加后的效果,但是测试时发现,图片右上角的删除不生效 下面在看到一个属性:dragSelecto

sven_chen93的博客 1648

第03章 Hermes Agent 核心原理

环境跑通之后,读者会很自然地想问:Hermes 的内部到底是怎么转起来的?为什么它能做到"越用越聪明"?长对话不会忘记上下文吗?这一章用尽量短的篇幅把核心原理讲清楚。理解原理不是为了纸上谈兵,而是为了在第7章实战时能判断"为什么 Hermes 这么响应"以及"我应该把哪类任务交给它"。

亢少军的博客 143

Agent Skills应用解析:构建可扩展、高效率AI探员

Agent Skills是一个简洁而强大的概念:它是一个包含组织化的指令、脚本和资源的文件夹,智能体可以动态地发现并加载这些内容,以在特定任务中表现更佳。可组合性(Composability):一个Agent Skill是一个独立的、封装良好的能力单元。开发者可以为不同的功能(例如PDF处理、网络浏览、数据分析)创建独立的技能,然后根据需要将它们组合起来,赋能不同的智能体。这意味着不再需要为每个用例构建碎片化、定制设计的智能体,而是可以通过组合现有技能来快速构建新的专业智能体。

形上得其象,形下合于数;阴阳自济,玄理自明。 1628

jquery插件之dragsort使用心得

昨天接到来公司第一个任务,这里总结一下。在今天下午以前我以为我可能永远都解决不了这个问题了,结果师兄刷刷几下的就解决了,我还是太傻了,唉。 遇到的第一个任务就是在一个已经基本成熟的项目里实现按一个小功能——拖拽功能: 使用场景:用户上传图片的时候选择了一些图片,用户可以通过用鼠标拖动图片,交换图片位置。 解决方案:使用jquery里面的一个dragsort插件。 遇到的问题(bug): ...

Homer_Simpson的博客 7338

① Django手把手从零开发个人博客-前言

手把手教你从零开始玩转手把手教你从零开始玩转Django,全面学习并了解django的运行机制、开发全流程及线上部署。Django,全面学习并了解django的运行机制、开发全流程及线上部署。 专栏介绍 本套教程遵循Django的设计思想,开门见山,快速切入主题,拒绝拖沓,在实战中学习每一个知识点,提高学习的趣味性以及个人成就感,并且能快速将所学运用到实际项目中。 将从零手把手带着你一步步完成博客的每一个功能,通过实现博客文章列表页、文章详情页、作者页面等功能来学习和了解django的视图查询模块相关知.

轻编程的博客 515

[jQuery] 两个ul之间li元素的拖拉和排序

HTML代码:<span class="left"><b>one</b><ul id="list1" style="background-color:#ffee00" name="offJob"><li>1</li><li>2</li><li>3</li><li&...

weixin_30580943的博客 201

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

dragsort html拖拽排序

一、Jquery List DragSort   对于有些页面,如首页的定制,需要进行动态的拖拽排序。由于自己实现比较困难,我们一般会使用一些js插件来实现。dragsort 就是帮助我们完成这一需求。通过dragsort我们可以很方便地对html页面上的素动态地推拽,进行排序。dragsort是一个jquery插件,我们使用起来非常方便。dragsort网站为:dragsort下载地址为:htt...

weixin_33985679的博客 355

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jquery dragsort table实现拖拽排序

转自:http://haoningabc.iteye.com/blog/1593640 dragsort官网地址:http://dragsort.codeplex.com/ html代码如下(需引入jquery和dragsort.js): <html> <head> <script type="tex...

weixin_30646315的博客 863

jquery表格、序列的拖拽排序dragsort

插件地址:http://dragsort.codeplex.com/ html部分: table情况,           id='tableid'>                                 ……                             或          >             

qm2010429的专栏 5031

jquery ui,拖拽,dragsort

一、导入js。导入jquery.dragsort.js外还需要导入jQuery。 二、HTML部分 <!DOCTYPE html> <html> <head> <title>DragSort Example </title> <meta charset="utf-8" />...

dibanmi2602的博客 330

jquery拖拽排序控件DragSort

官网: dragsort.codeplex.com 引入jquery包 然后导入diagsort包 使用 $("ul").dragsort() 默认拖拽的标签的li 可以通过修改dragSelector参数实现拖拽其他标签 例如拖拽tr标签 $("table").dragsort({ dragSelector: "tr"}) 停止拖拽

贱贱的刁民的技术博客 1万+

jQuery图片拖动插件DragSort

jquery list dragsort列表拖动插件使用方法 $("ul").dragsort({     dragSelector: "li",     dragEnd: function() { },     dragBetween: false,     placeHolderTemplate: "" }); jquery list dragsort列表拖动插件参数说明

150

dragsort:很不错的拖动排序zujian

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33834628的博客 319

JQuery list dragsort 拖放插件

Jquery list dragsort插件能对ul的li进行排序,实现列表拖动排序效果。   插件下载地址:http://dragsort.codeplex.com/ Demo地址:    http://www.uedsc.com/wp-content/uploads/2014/04/jquery-list-dragsort/   jquery list dragsort列表拖动插件...

a406502972的专栏 696

用dragsort +bootstrap+php实现 table拖动自动保持排序,前面加序号及时更新效果

php+ajax+dragsort插件+bootstrap美化实现拖拽排序,保持序号不变,但真实排序保持变化。 代码说明: my.js为自定义ajax请求,定义了数据接收处理和发送给后台php方法。里面有具体处理数据的样式以及php处理js发送数据保存到数据库的小demo。 jquery.dragsort-0.5.2.js 为插件内容,...

weixin_33912445的博客 413

js拖拽功能

$("#datatable").find("tbody").attr("id","tbodyId"); /* 拖拽功能 $("#tbodyId").dragsort({ itemSelector: "tr", dragSelector: "tr", dragBetween: false, //dragEnd: save...

fjbadm的专栏 476

实现Bootstrap表格拖拽

实现Bootstrap表格拖拽: 需要引入jquery.min.js、bootstrap相关文件,以及jquery.dragsort-0.5.2.js 代码如下: 1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <script type="text/javascript" s...

weixin_30390075的博客 443
上一篇: java poi 导入excel时 读取单元格内容的方法 ,其中包含excel中有函数的读法
下一篇: 将Select转变为支持输入内容对Select的Option进行筛选的js
ole_triangle_java
博客等级 码龄10年 82粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值