zui
Version:
一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。
205 lines (179 loc) • 6.42 kB
JavaScript
/* ========================================================================
* ZUI: draggable.js
* http://zui.sexy
* ========================================================================
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
* ======================================================================== */
(function($, document) {
'use strict';
var NAME = 'zui.draggable',
DEFAULTS = {
// selector: '',
container: 'body',
move: true
// mouseButton: -1 // 0, 1, 2, -1, all, left, right, middle
};
var idIncrementer = 0;
var Draggable = function(element, options) {
var that = this;
that.$ = $(element);
that.id = idIncrementer++;
that.options = $.extend({}, DEFAULTS, that.$.data(), options);
that.init();
};
Draggable.DEFAULTS = DEFAULTS;
Draggable.NAME = NAME;
Draggable.prototype.init = function() {
var that = this,
$root = that.$,
BEFORE = 'before',
DRAG = 'drag',
FINISH = 'finish',
eventSuffix = '.' + NAME + '.' + that.id,
mouseDownEvent = 'mousedown' + eventSuffix,
mouseUpEvent = 'mouseup' + eventSuffix,
mouseMoveEvent = 'mousemove' + eventSuffix,
setting = that.options,
selector = setting.selector,
handle = setting.handle,
$ele = $root,
isMoveFunc = $.isFunction(setting.move),
startPos,
cPos,
startOffset,
mousePos,
moved;
var mouseMove = function(event) {
var mX = event.pageX,
mY = event.pageY;
moved = true;
var dragPos = {
left: mX - startOffset.x,
top: mY - startOffset.y
};
$ele.removeClass('drag-ready').addClass('dragging');
if(setting.move) {
if (isMoveFunc) {
setting.move(dragPos, $ele);
} else {
$ele.css(dragPos);
}
}
setting[DRAG] && setting[DRAG]({
event: event,
element: $ele,
startOffset: startOffset,
pos: dragPos,
offset: {
x: mX - startPos.x,
y: mY - startPos.y
},
smallOffset: {
x: mX - mousePos.x,
y: mY - mousePos.y
}
});
mousePos.x = mX;
mousePos.y = mY;
if(setting.stopPropagation) {
event.stopPropagation();
}
};
var mouseUp = function(event) {
$(document).off(eventSuffix);
if(!moved) {
$ele.removeClass('drag-ready');
return;
}
var endPos = {
left: event.pageX - startOffset.x,
top: event.pageY - startOffset.y
};
$ele.removeClass('drag-ready dragging');
if(setting.move) {
if (isMoveFunc) {
setting.move(endPos, $ele);
} else {
$ele.css(endPos);
}
}
setting[FINISH] && setting[FINISH]({
event: event,
element: $ele,
startOffset: startOffset,
pos: endPos,
offset: {
x: event.pageX - startPos.x,
y: event.pageY - startPos.y
},
smallOffset: {
x: event.pageX - mousePos.x,
y: event.pageY - mousePos.y
}
});
event.preventDefault();
if(setting.stopPropagation) {
event.stopPropagation();
}
};
var mouseDown = function(event) {
var mouseButton = $.zui.getMouseButtonCode(setting.mouseButton);
if(mouseButton > -1 && event.button !== mouseButton) {
return;
}
var $mouseDownEle = $(this);
if(selector) {
$ele = handle ? $mouseDownEle.closest(selector) : $mouseDownEle;
}
if(setting[BEFORE]) {
var isSure = setting[BEFORE]({
event: event,
element: $ele
});
if(isSure === false) return;
}
var $container = $(setting.container),
pos = $ele.offset();
cPos = $container.offset();
startPos = {
x: event.pageX,
y: event.pageY
};
startOffset = {
x: event.pageX - pos.left + cPos.left,
y: event.pageY - pos.top + cPos.top
};
mousePos = $.extend({}, startPos);
moved = false;
$ele.addClass('drag-ready');
event.preventDefault();
if(setting.stopPropagation) {
event.stopPropagation();
}
$(document).on(mouseMoveEvent, mouseMove).on(mouseUpEvent, mouseUp);
};
if(handle) {
$root.on(mouseDownEvent, handle, mouseDown);
} else if(selector) {
$root.on(mouseDownEvent, selector, mouseDown);
} else {
$root.on(mouseDownEvent, mouseDown);
}
};
Draggable.prototype.destroy = function() {
var eventSuffix = '.' + NAME + '.' + this.id;
this.$.off(eventSuffix);
$(document).off(eventSuffix);
this.$.data(NAME, null);
};
$.fn.draggable = function(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAME);
var options = typeof option == 'object' && option;
if(!data) $this.data(NAME, (data = new Draggable(this, options)));
if(typeof option == 'string') data[option]();
});
};
$.fn.draggable.Constructor = Draggable;
}(jQuery, document));