dragsort html拖拽排序 的应用

/**
 *
 *
 * 设置参数的说明:
 * 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);



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值