Skip to content
Browse files

Another version

  • Loading branch information...
1 parent 8b3a9e8 commit 1a02d9716c65f1d13924e04a2ffba486611f9a5b @mmavko committed
Showing with 149 additions and 53 deletions.
  1. +1 −1 README.md
  2. +104 −0 sort-absolute.js
  3. +44 −52 sort.js
View
2 README.md
@@ -2,4 +2,4 @@
Javascript Sortable List
========================
-Sortable list implementation based on jQuery.
+Sortable list implementation based on jQuery (or Zepto?) that uses CSS3 transitions.
View
104 sort-absolute.js
@@ -0,0 +1,104 @@
+
+Sort = (function () {
+ function _bind(f, scope) {
+ return function () {
+ f.apply(scope, arguments);
+ }
+ }
+ function Sort (el, options) {
+ $.extend(this, this.constructor.defaultOptions, options);
+ this.$list = $(el).first().css({position: 'relative'});
+ $(document).on({
+ mousemove: _bind(this.onMouseMove, this),
+ mouseup: _bind(this.onMouseUp, this)
+ });
+ this.refreshItems();
+ this.$items.on({
+ mousedown: _bind(this.onMouseDown, this)
+ });
+ this.$items.last().after(this.$items.last().clone().css('display', 'none'));
+ this.refreshItems();
+ this.height = this.$items.get(1).offsetTop - this.$items.get(0).offsetTop;
+ };
+ Sort.defaultOptions = {
+ itemsSelector: 'li'
+ };
+ Sort.prototype = {
+ refreshItems: function () {
+ this.$items = this.$list.children(this.itemsSelector);
+ },
+ onMouseDown: function (e) {
+ this.$target = $(e.target);
+ this.x1 = e.pageX;
+ this.y1 = e.pageY;
+ this.start();
+ e.preventDefault();
+ },
+ onMouseMove: function (e) {
+ if (!this.$target) return;
+ var
+ dx = e.pageX - this.x1,
+ dy = e.pageY - this.y1,
+ di = Math.round(dy / this.height);
+ this.$target.css({
+ top: this.top + dy,
+ left: this.left + dx
+ });
+ if (di !== this.lastDi) this.move(di);
+ this.lastDi = di;
+ },
+ onMouseUp: function (e) {
+ if (!this.$target) return;
+ this.end();
+ },
+ start: function () {
+ this.$placeholder = this.$target.clone().html(' ');
+ var staticPos = this.$target.position();
+ this.$target.css({
+ width: this.$target.css('width'),
+ position: 'absolute'
+ });
+ $.extend(this, this.$target.position());
+ // include collapsed margins if any
+ if (staticPos.top < 0) this.top += staticPos.top;
+ this.$target.css({
+ top: this.top,
+ left: this.left
+ }).before(this.$placeholder);
+ },
+ move: function (di) {
+ // skip target item
+ if (di > 0) di++;
+ var
+ i = this.$items.index(this.$target.get(0)),
+ current, ci = i + di,
+ maxi = this.$items.length-1;
+ // move placeholder
+ this.$placeholder.detach();
+ if (ci < 0) ci = 0;
+ if (i+di > maxi) ci = maxi;
+ current = this.$items.get(ci);
+ $(current).before(this.$placeholder);
+ },
+ end: function () {
+ // move target
+ this.$target.detach();
+ this.$placeholder.before(this.$target);
+ this.stop();
+ this.refreshItems();
+ },
+ stop: function () {
+ this.$placeholder.remove();
+ this.$target.css({
+ position: '',
+ top: '',
+ left: '',
+ width: ''
+ });
+ delete this.$placeholder;
+ delete this.$target;
+ delete this.lastDi;
+ }
+ };
+ return Sort;
+})();
View
96 sort.js
@@ -7,18 +7,17 @@ Sort = (function () {
}
function Sort (el, options) {
$.extend(this, this.constructor.defaultOptions, options);
- this.$list = $(el).first().css({position: 'relative'});
+ this.$list = $(el).first();
+ this.refreshItems();
+ this.$items.css('position', 'relative');
+ this.height = this.$items.get(1).offsetTop - this.$items.get(0).offsetTop;
$(document).on({
mousemove: _bind(this.onMouseMove, this),
mouseup: _bind(this.onMouseUp, this)
});
- this.refreshItems();
this.$items.on({
mousedown: _bind(this.onMouseDown, this)
});
- this.$items.last().after(this.$items.last().clone().css('display', 'none'));
- this.refreshItems();
- this.height = this.$items.get(1).offsetTop - this.$items.get(0).offsetTop;
};
Sort.defaultOptions = {
itemsSelector: 'li'
@@ -36,66 +35,59 @@ Sort = (function () {
},
onMouseMove: function (e) {
if (!this.$target) return;
- var
- dx = e.pageX - this.x1,
- dy = e.pageY - this.y1,
- di = Math.round(dy / this.height);
- this.$target.css({
- top: this.top + dy,
- left: this.left + dx
- });
- if (di !== this.lastDi) this.move(di);
- this.lastDi = di;
+ this.move(e.pageX - this.x1, e.pageY - this.y1);
},
onMouseUp: function (e) {
if (!this.$target) return;
this.end();
+ delete this.$target;
+ delete this.x1;
+ delete this.y1;
},
start: function () {
- this.$placeholder = this.$target.clone().html('&nbsp;');
- var staticPos = this.$target.position();
+ this.$items.not(this.$target).css('-webkit-transition', 'top 0.1s');
+ this.$target.css('z-index', 1);
+ // store target index
+ this.ti = this.$items.index(this.$target);
+ },
+ move: function (dx, dy) {
this.$target.css({
- width: this.$target.css('width'),
- position: 'absolute'
+ top: dy,
+ left: dx
});
- $.extend(this, this.$target.position());
- // include collapsed margins if any
- if (staticPos.top < 0) this.top += staticPos.top;
- this.$target.css({
- top: this.top,
- left: this.left
- }).before(this.$placeholder);
- },
- move: function (di) {
- // skip target item
- if (di > 0) di++;
- var
- i = this.$items.index(this.$target.get(0)),
- current, ci = i + di,
- maxi = this.$items.length-1;
- // move placeholder
- this.$placeholder.detach();
- if (ci < 0) ci = 0;
- if (i+di > maxi) ci = maxi;
- current = this.$items.get(ci);
- $(current).before(this.$placeholder);
+ // index delta
+ var di = Math.round(dy / this.height);
+ if (di === this.di) return;
+ this.di = di;
+ // current index
+ var ci = this.ti + this.di;
+ // adjust positions
+ this.$items.each(_bind(function (i, item) {
+ if (i == this.ti) return true;
+ var top = '';
+ if (i >= ci && i < this.ti) top = this.height;
+ if (i <= ci && i > this.ti) top = -this.height;
+ $(item).css('top', top);
+ }, this));
},
end: function () {
- this.$target.detach();
- this.$placeholder.before(this.$target);
- this.stop();
- this.refreshItems();
- },
- stop: function () {
- this.$placeholder.remove();
- this.$target.css({
- position: '',
+ this.$items.css({
top: '',
left: '',
- width: ''
+ '-webkit-transition': '',
+ 'z-index': ''
});
- delete this.$placeholder;
- delete this.$target;
+ var
+ ci = this.ti + this.di,
+ maxi = this.$items.length-1,
+ func = 'after';
+ if (ci < 0) ci = 0;
+ if (ci > maxi) ci = maxi;
+ if (this.di < 0) func = 'before';
+ if (this.di !== 0) $(this.$items.get(ci))[func](this.$target);
+ delete this.di;
+ delete this.ti;
+ this.refreshItems();
}
};
return Sort;

0 comments on commit 1a02d97

Please sign in to comment.
Something went wrong with that request. Please try again.