diff --git a/ddsort.js b/ddsort.js index 6fb5cd3..6a98084 100644 --- a/ddsort.js +++ b/ddsort.js @@ -54,8 +54,10 @@ var self = this; var $this = $(self); + // 鼠标按下时的元素偏移 var offset = $this.offset(); + // 鼠标按下时的光标坐标 // 桌面端 var pageX = e.pageX; var pageY = e.pageY; @@ -67,9 +69,6 @@ pageY = targetTouches[0].pageY; } - var disX = pageX - offset.left; - var disY = pageY - offset.top; - var clone = $this.clone() .css(settings.cloneStyle) .css('height', $this[height]()) @@ -78,30 +77,37 @@ var hasClone = 1; // 缓存计算 - var thisOuterHeight = $this.outerHeight(); - var thatOuterHeight = that.outerHeight(); + var thisOuterHeight = $this.outerHeight(), + thisOuterWidth = $this.outerWidth(), + thatOuterHeight = that.outerHeight(), + thatOuterWidth = that.outerWidth(); // 滚动速度 - var upSpeed = thisOuterHeight; - var downSpeed = thisOuterHeight; - var maxSpeed = thisOuterHeight * 3; + var upSpeed = thisOuterHeight, + downSpeed = thisOuterHeight, + leftSpeed = thisOuterWidth, + rightSpeed = thisOuterWidth, + maxSpeed = thisOuterHeight * 3; settings.down.call(self); $doc.on('mousemove.DDSort touchmove.DDSort', function (e) { + // 鼠标移动时的光标坐标 // 桌面端 - var pageX = e.pageX; - var pageY = e.pageY; + var _pageX = e.pageX; + var _pageY = e.pageY; // 移动端 var targetTouches = e.originalEvent.targetTouches; if (e.type == 'touchmove' && targetTouches) { - pageX = targetTouches[0].pageX; - pageY = targetTouches[0].pageY; + _pageX = targetTouches[0].pageX; + _pageY = targetTouches[0].pageY; } - if (new Date().getTime() - startTime < settings.delay) return; + if (new Date().getTime() - startTime < settings.delay) { + return; + } if (hasClone) { $this.before(clone) @@ -112,54 +118,75 @@ hasClone = 0; } - var left = pageX - disX; - var top = pageY - disY; - - var prev = clone.prev(); - var next = clone.next().not($this); - - // 超出首屏减去页面滚动条高度或宽度 - $this.css({ - left: left - $doc.scrollLeft(), - top: top - $doc.scrollTop() + var disX = pageX - _pageX; + var disY = pageY - _pageY; + var left = offset.left - disX; + var top = offset.top - disY; + + $this.offset({ + left: left, + top: top }); - // 向上排序 - if (prev.length && top < prev.offset().top + prev.outerHeight() / 2) { + var $left = getLeft(clone), + $right = getRight(clone, $this), + $top = getTop(clone), + $under = getUnder(clone, $this); - clone.after(prev); + if ($top && $top.length && top < $top.offset().top + $top.outerHeight(true) / 2) { + // 向上排序 + $top.before(clone); + + } else if ($under && $under.length && top + thisOuterHeight > $under.offset().top + $under.outerHeight(true) / 2) { // 向下排序 - } else if (next.length && top + thisOuterHeight > next.offset().top + next.outerHeight() / 2) { - - clone.before(next); - + $under.after(clone); + + } else if($left && $left.length && left < $left.offset().left + $left.outerWidth(true) / 2) { + //向左排序 + $left.before(clone); + + } else if($right && $right.length && left + thisOuterWidth > $right.offset().left + $right.outerWidth(true) / 2) { + //向右排序 + $right.after(clone); + } // 处理滚动条,that 是带着滚动条的元素,这里默认以为 that 元素是这样的元素(正常情况就是这样), // 如果使用者事件委托的元素不是这样的元素,那么需要提供接口出来 var thatScrollTop = that.scrollTop(); var thatOffsetTop = that.offset().top; - var scrollVal; - - // 向上滚动 if (top < thatOffsetTop) { - + // 向上滚动 downSpeed = thisOuterHeight; upSpeed = ++upSpeed > maxSpeed ? maxSpeed : upSpeed; - scrollVal = thatScrollTop - upSpeed; - - // 向下滚动 + var scrollVal = thatScrollTop - upSpeed; + that.scrollTop(scrollVal); } else if (top + thisOuterHeight - thatOffsetTop > thatOuterHeight) { - + // 向下滚动 upSpeed = thisOuterHeight; downSpeed = ++downSpeed > maxSpeed ? maxSpeed : downSpeed; - scrollVal = thatScrollTop + downSpeed; + var scrollVal = thatScrollTop + downSpeed; + that.scrollTop(scrollVal); } - that.scrollTop(scrollVal); + var thatScrollLeft = that.scrollLeft(); + var thatOffsetLeft = that.offset().left; + if (left < that.offset().left) { + // 向左滚动 + rightSpeed = thisOuterWidth; + leftSpeed = ++leftSpeed > maxSpeed ? maxSpeed : leftSpeed; + var scrollVal = thatScrollLeft - leftSpeed; + that.scrollLeft(scrollVal); + } else if (left + thisOuterWidth - thatOffsetLeft > thatOuterWidth) { + // 向右滚动 + leftSpeed = thisOuterWidth; + rightSpeed = ++rightSpeed > maxSpeed ? maxSpeed : rightSpeed; + var scrollVal = thatScrollLeft + rightSpeed; + that.scrollLeft(scrollVal); + } - settings.move.call(self, left - $doc.scrollLeft(), top - $doc.scrollTop()); + settings.move.call(self, left, top); }) .on('mouseup.DDSort touchend.DDSort', function () { @@ -176,4 +203,59 @@ }); }); }; + + + //允许计算误差 + var deviation = 5; + + var getLeft = function (clone) { + var left = clone.prev(); + if(left.length && clone.offset().top==left.offset().top) { + var _dev = Math.abs(clone.offset().left - (left.offset().left + left.outerWidth(true))); + if(_dev <= deviation) { + return left; + } + } + return undefined; + } + var getTop = function (clone, prev) { + if(!prev){ + prev = clone.prev(); + } + if(!prev.length) { + return undefined; + } + if(clone.offset().left==prev.offset().left) { + var _dev = Math.abs(clone.offset().top - (prev.offset().top+prev.outerHeight(true))); + if(_dev <= deviation) { + return prev; + } + } + return getTop(clone, prev.prev()); + } + var getRight = function (clone, $this) { + var rigth = clone.next().not($this); + if(rigth.length && clone.offset().top==rigth.offset().top) { + var _dev = Math.abs(clone.offset().left - (rigth.offset().left-clone.outerWidth(true))); + if(_dev <= deviation) { + return rigth; + } + } + return undefined; + } + var getUnder = function (clone, $this, next) { + if(!next){ + next = clone.next().not($this); + } + if(!next.length) { + return undefined; + } + if(clone.offset().left==next.offset().left) { + var _dev = Math.abs(clone.offset().top - (next.offset().top-clone.outerHeight(true))); + if(_dev <= deviation) { + return next; + } + } + return getUnder(clone, $this, next.next().not($this)); + } }(jQuery); diff --git a/ddsort.min.js b/ddsort.min.js index 608866d..7de53f7 100644 --- a/ddsort.min.js +++ b/ddsort.min.js @@ -2,4 +2,4 @@ * DDSort: drag and drop sorting. * Documentation: https://github.com/Barrior/DDSort */ -+function(b){var a={down:b.noop,move:b.noop,up:b.noop,target:"li",delay:100,cloneStyle:{"background-color":"#eee"},floatStyle:{position:"fixed","box-shadow":"10px 10px 20px 0 #eee",webkitTransform:"rotate(4deg)",mozTransform:"rotate(4deg)",msTransform:"rotate(4deg)",transform:"rotate(4deg)"}};b.fn.DDSort=function(c){var e=b(document);var d=b.extend(true,{},a,c);return this.each(function(){var g=b(this);var h="height";var f="width";if(g.css("box-sizing")=="border-box"){h="outerHeight";f="outerWidth"}g.on("mousedown.DDSort touchstart.DDSort",d.target,function(v){var z=new Date().getTime();if(v.type=="mousedown"&&v.which!=1){return}var s=v.target.tagName.toLowerCase();if(s=="input"||s=="textarea"||s=="select"||s=="a"||b(v.target).prop("contenteditable")=="true"){return}var t=this;var o=b(t);var n=o.offset();var j=v.pageX;var i=v.pageY;var w=v.originalEvent.targetTouches;if(v.type=="touchstart"&&w){j=w[0].pageX;i=w[0].pageY}var m=j-n.left;var l=i-n.top;var x=o.clone().css(d.cloneStyle).css("height",o[h]()).empty();var r=1;var k=o.outerHeight();var u=g.outerHeight();var p=k;var q=k;var y=k*3;d.down.call(t);e.on("mousemove.DDSort touchmove.DDSort",function(F){var D=F.pageX;var C=F.pageY;var H=F.originalEvent.targetTouches;if(F.type=="touchmove"&&H){D=H[0].pageX;C=H[0].pageY}if(new Date().getTime()-zE.offset().top+E.outerHeight()/2){x.before(E)}}var K=g.scrollTop();var J=g.offset().top;var G;if(Iy?y:p;G=K-p}else{if(I+k-J>u){p=k;q=++q>y?y:q;G=K+q}}g.scrollTop(G);d.move.call(t,A-e.scrollLeft(),I-e.scrollTop())}).on("mouseup.DDSort touchend.DDSort",function(){e.off("mousemove.DDSort mouseup.DDSort touchmove.DDSort touchend.DDSort");if(!r){x.before(o.removeAttr("style")).remove();d.up.call(t)}});return false})})}}(jQuery); \ No newline at end of file ++function(e){var b={down:e.noop,move:e.noop,up:e.noop,target:"li",delay:100,cloneStyle:{"background-color":"#eee"},floatStyle:{"position":"fixed","box-shadow":"10px 10px 20px 0 #eee","webkitTransform":"rotate(4deg)","mozTransform":"rotate(4deg)","msTransform":"rotate(4deg)","transform":"rotate(4deg)"}};e.fn.DDSort=function(h){var j=e(document);var i=e.extend(true,{},b,h);return this.each(function(){var m=e(this);var k="height";var l="width";if(m.css("box-sizing")=="border-box"){k="outerHeight";l="outerWidth"}m.on("mousedown.DDSort touchstart.DDSort",i.target,function(D){var z=new Date().getTime();if(D.type=="mousedown"&&D.which!=1){return}var s=D.target.tagName.toLowerCase();if(s=="input"||s=="textarea"||s=="select"||s=="a"||e(D.target).prop("contenteditable")=="true"){return}var A=this;var v=e(A);var u=v.offset();var p=D.pageX;var o=D.pageY;var F=D.originalEvent.targetTouches;if(D.type=="touchstart"&&F){p=F[0].pageX;o=F[0].pageY}var E=v.clone().css(i.cloneStyle).css("height",v[k]()).empty();var x=1;var y=v.outerHeight(),B=v.outerWidth(),C=m.outerHeight(),n=m.outerWidth();var t=y,w=y,q=B,r=B,G=y*3;i.down.call(A);j.on("mousemove.DDSort touchmove.DDSort",function(O){var N=O.pageX;var M=O.pageY;var Q=O.originalEvent.targetTouches;if(O.type=="touchmove"&&Q){N=Q[0].pageX;M=Q[0].pageY}if(new Date().getTime()-zR.offset().top+R.outerHeight(true)/2){R.after(E)}else{if(H&&H.length&&JT.offset().left+T.outerWidth(true)/2){T.after(E)}}}}var V=m.scrollTop();var U=m.offset().top;if(SG?G:t;var P=V-t;m.scrollTop(P)}else{if(S+y-U>C){t=y;w=++w>G?G:w;var P=V+w;m.scrollTop(P)}}var K=m.scrollLeft();var I=m.offset().left;if(JG?G:q;var P=K-q;m.scrollLeft(P)}else{if(J+B-I>n){q=B;r=++r>G?G:r;var P=K+r;m.scrollLeft(P)}}i.move.call(A,J,S)}).on("mouseup.DDSort touchend.DDSort",function(){j.off("mousemove.DDSort mouseup.DDSort touchmove.DDSort touchend.DDSort");if(!x){E.before(v.removeAttr("style")).remove();i.up.call(A)}});return false})})};var c=5;var a=function(j){var i=j.prev();if(i.length&&j.offset().top==i.offset().top){var h=Math.abs(j.offset().left-(i.offset().left+i.outerWidth(true)));if(h<=c){return i}}return undefined};var d=function(j,i){if(!i){i=j.prev()}if(!i.length){return undefined}if(j.offset().left==i.offset().left){var h=Math.abs(j.offset().top-(i.offset().top+i.outerHeight(true)));if(h<=c){return i}}return d(j,i.prev())};var g=function(k,j){var i=k.next().not(j);if(i.length&&k.offset().top==i.offset().top){var h=Math.abs(k.offset().left-(i.offset().left-k.outerWidth(true)));if(h<=c){return i}}return undefined};var f=function(k,j,i){if(!i){i=k.next().not(j)}if(!i.length){return undefined}if(k.offset().left==i.offset().left){var h=Math.abs(k.offset().top-(i.offset().top-k.outerHeight(true)));if(h<=c){return i}}return f(k,j,i.next().not(j))}}(jQuery); \ No newline at end of file diff --git a/demo_multi_direction.html b/demo_multi_direction.html new file mode 100644 index 0000000..80b447a --- /dev/null +++ b/demo_multi_direction.html @@ -0,0 +1,157 @@ + + + + + + DDSort + + + +
+
    +
  • + 世界上最美好的相遇是恰好,你洽好青春年少,我恰好青春芳华; + 世界上最唯美的惊艳是偶然,你偶然出现,我偶然发现, + 然后清纯的两颗心,慢慢地慢慢地靠近; +
  • +
  • + 你飘逸的裙裾逶迤在我寂寞里飞马行空的诗行,
    + 跟随你的优雅舒缓的步履, +
  • +
  • + 在相濡以沫心心相印的平凡日子里心香如故,
    + 刻写一个个浪漫和感动记忆的满面皱纹。 +
  • +
  • + 除了怀念,只剩怀念;
    + 除了无言,只能无言! +
  • +
  • + 你飘逸的裙裾逶迤在我寂寞里飞马行空的诗行,
    + 跟随你的优雅舒缓的步履, +
  • +
  • + 在相濡以沫心心相印的平凡日子里心香如故,
    + 刻写一个个浪漫和感动记忆的满面皱纹。 +
  • +
  • + 除了怀念,只剩怀念;
    + 除了无言,只能无言! +
  • +
  • + 你飘逸的裙裾逶迤在我寂寞里飞马行空的诗行,
    + 跟随你的优雅舒缓的步履, +
  • +
  • + 在相濡以沫心心相印的平凡日子里心香如故,
    + 刻写一个个浪漫和感动记忆的满面皱纹。 +
  • +
  • + 除了怀念,只剩怀念;
    + 除了无言,只能无言! +
  • +
  • 一些事情,你愈是去遮掩愈是容易清晰,原本以为的瞒天过海,结果却是欲盖弥彰。
  • +
  • + A 链接测试: + music.163.com +
  • +
  • + 图片测试: + ddsort +
  • +
  • + input element 测试: + +
  • +
  • + contenteditable element 测试: +
    一些内容,内容...
    +
  • +
  • + 等待永远是漫长的,看不到时间,看不清即将到来,在等着,等到焦灼。甚至有时自己都会恍惚,是在等即将到来,还是等到来时的那一刻欣喜,这份欣喜里藏着那不言而喻的激动与渴望。 +
  • +
  • + 暖暖的午后,睡梦中惊醒,懒懒的将手机拿至眼前,习惯性的快速浏览一下朋友圈,一篇暖文《生命,是一场等待》瞬间定格了我的眼球,文章中有一句话我非常喜欢 +
  • +
  • + 也许,在一个阳光明媚的日子里,你兴高采烈的郊游,看到那么绿的草,艳的花,心里很是愉悦,感觉这世界尽是美的。 +
  • +
  • + 人生需要规划,尤其是在25岁之后,如果还拎不清,胡里糊涂的,那么你明白的就太迟了。 +
  • +
  • + 也许是越来越多的人抛弃了农村老家,进城生活,我们这个时代,从来没有像今天这样,深切地关注、谈论乡愁。 +
  • +
+
+ + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 347ff35..494ed96 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,9 @@

DDSort Demo List

  • demo_bootstrap.html
  • +
  • + demo_multi_direction.html +
  • \ No newline at end of file