/*
* 简易的拖拽插件
* new Drag([selector],[options]);
* SELECTOR
* 按住谁来实现拖拽
* OPTIONS = {}
* element:拖拽中要移动的元素(默认值:当前按住的元素)
* boundary:是否进行边界校验 (默认值:true,不能超过要移动元素所在容器的范围,需要开发者保证:
当前移动的元素是相对于它所在容器定位的)
*
* 声明周期函数(钩子函数)
* dragstart:拖拽开始
* dragmove:拖拽中
* dragend:拖拽结束
*/
~ function () {
/*
* 拖拽插件封装
*/
class Drag {
constructor(selector, options) {
this.initParams(selector, options);
this._selector.addEventListener('mousedown', this.down.bind(this));
}
// 参数初始化(尽可能把一切信息都挂载到实例上,这样在其它方法中,只要能获取到实例,这些信息都可以调用 => 我们尽可能保证每个方法中的 THIS 都是实例)
initParams(selector, options = {}) {
this._selector = document.querySelector(selector);
// 配置项的默认值信息
let defaultParams = {
element: this._selector,
boundary: true,
dragstart: null,
dragmove: null,
dragend: null
};
defaultParams = Object.assign(defaultParams, options);
// 把配置项信息都挂载到实例上
Drag.each(defaultParams, (value, key) => {
this['_' + key] = value;
});
}
// 实现拖拽的效果
down(ev) {
let {
_element
} = this;
this.startX = ev.pageX;
this.startY = ev.pageY;
this.startL = Drag.queryCss(_element, 'left');
this.startT = Drag.queryCss(_element, 'top');
this._move = this.move.bind(this);
this._up = this.up.bind(this);
document.addEventListener('mousemove', this._move);
document.addEventListener('mouseup', this._up);
// 钩子函数处理
this._dragstart && this._dragstart(this, ev);
}
move(ev) {
let {_element, _boundary, startX, startY, startL, startT} = this;
let curL = ev.pageX - startX + startL,
curT = ev.pageY - startY + startT;
if (_boundary) {
// 处理边界
let parent = _element.parentNode,
minL = 0,
minT = 0,
maxL = parent.offsetWidth - _element.offsetWidth,
maxT = parent.offsetHeight - _element.offsetHeight;
curL = curL < minL ? minL : (curL > maxL ? maxL : curL);
curT = curT < minT ? minT : (curT > maxT ? maxT : curT);
}
_element.style.left = curL + 'px';
_element.style.top = curT + 'px';
// 钩子函数处理
this._dragmove && this._dragmove(this, curL, curT, ev);
}
up(ev) {
document.removeEventListener('mousemove', this._move);
document.removeEventListener('mouseup', this._up);
// 钩子函数处理
this._dragend && this._dragend(this, ev);
}
// 设置工具类的方法(把它当做类[普通对象]的私有属性)
static each(arr, callback) {
if ('length' in arr) {
// 数组 || 类数组
for (let i = 0; i < arr.length; i++) {
callback && callback(arr[i], i);
}
return;
}
// 普通对象
for (let key in arr) {
if (!arr.hasOwnProperty(key)) break;
callback && callback(arr[key], key);
}
}
static queryCss(curEle, attr) {
return parseFloat(window.getComputedStyle(curEle)[attr]);
}
}
window.Drag = Drag;
}();