// 用法:
// var hai = $('.hai_ning');
// hai.drag();
// 自定义配置
/* hai.drag({
xmax: x轴方向最大边缘,
xmin: 0,
ymax: '200px',
ymin: 0
}); */
$.extend({
/**
* 获取元素支持的transform
* @returns {string}
*/
getTransform: function() {
var prefix = ["", "-webkit-", "-moz-", "-o-", "-ms-"];
var style = document.createElement("div").style;
var transform = "",
i = 0,
len = prefix.length;
for (; i < len; i++) {
let t = prefix[i] + "transform";
if (t in style) {
return (transform = t);
}
}
return transform;
},
/**
* 获取鼠标位置
* @param { Event } e 事件对象
* @returns { object } 坐标
*/
getControlPos: function(e) {
let pos = null;
if (/mouse/.test(e.type)) {
return (pos = {
x: e.clientX,
y: e.clientY
});
} else if (/touch/.test(e.type)) {
return (pos = {
x: e.pageX,
y: e.pageY
});
}
return pos;
}
});
$.fn.extend({
/**
* 获取目标元素的位置
* @returns {object} 坐标
*/
getTargetPos: function() {
var pos = {
x: 0,
y: 0
};
var el = this[0];
var transform = $.getTransform();
// 找到浏览器所支持的transform
if (transform !== "") {
var transformValue = this.css("transform");
// 如果没有设置transform
if (transformValue === "none") {
el.style[transform] = "translate(0, 0)";
return pos;
} else {
var tmp = transformValue.match(/-?\d+/g); // transformValue: matrix(1, 0, 0, 1, 0, 0)
return (pos = {
x: parseInt(tmp[4].trim()),
y: parseInt(tmp[5].trim())
});
}
} else {
// 浏览器不支持transform, 则用相对定位方式
var positionValue = this.css("position");
if (positionValue === "static") {
el.style["position"] = "relative";
return pos;
} else {
return (pos = {
x: parseInt(this.css("left")),
y: parseInt(this.css("top"))
});
}
}
},
/**
* 设置元素位置
* @param { object } pos 坐标{x, y}
* @returns { number } 0: 失败, 1成功
*/
setTargetPos: function(pos) {
var edge = this.edge;
var transform = $.getTransform();
if (pos.x <= edge.xmin) {
pos.x = edge.xmin;
}
if (pos.x >= edge.xmax) {
pos.x = edge.xmax;
}
if (pos.y <= edge.ymin) {
pos.y = edge.ymin;
}
if (pos.y >= edge.ymax) {
pos.y = edge.ymax;
}
if (transform) {
this.css('transform', `translate(${pos.x}px, ${pos.y}px)`);
return 1;
} else {
this.css({
'left': pos.x + "px",
'top': pos.y + "px"
});
return 1;
}
return 0;
},
/**
* 拖拽接口函数
* @param {Object} options {xmax: x轴最大边缘,xmin: x轴最小边缘,ymax: ...ymin: ..}
*/
drag: function(options) {
var offset = this.offset();
var defaults = {
xmax: document.documentElement.clientWidth - offset["width"] - 1,
ymax: document.documentElement.clientHeight - offset["height"] - 1,
xmin: 0,
ymin: 0
};
this.edge = options || defaults;
var MOBILE = "ontouchstart" in window;
var target = this;
var el = this[0];
var state = {
moving: false, // 是否正在移动
startX: 0, // 鼠标的初始位置
startY: 0,
sourceX: 0, // 目标元素的初始位置
sourceY: 0
};
/**
* 重新设置目标状态
*/
var setTargetState = function() {
var targetPos = target.getTargetPos();
state.sourceX = targetPos.x;
state.sourceY = targetPos.y;
};
/**
* 移动目标
* @param {Event} e mousemove事件
*/
var move = function(e) {
if (!state.moving) {
return;
}
var { x, y } = target.getControlPos(e),
dx = x - state.startX, // 计算鼠标偏移量
dy = y - state.startY;
target.setTargetPos({
x: (state.sourceX + dx).toFixed(),
y: (state.sourceY + dy).toFixed()
});
};
/**
* 放下目标
*/
var end = function() {
setTargetState(el);
state.moving = false;
if (!MOBILE) {
$(document).unbind("mousemove", move);
$(document).unbind("mouseup", end);
} else {
$(document).unbind("touchmove", move);
$(document).unbind("touchend", end);
}
console.log("move end");
};
/**
* 抱起目标
* @param {Event} e mousedown事件
*/
var start = function() {
var controlPos = target.getControlPos(e);
setTargetState(el);
state.moving = true;
state.startX = controlPos.x;
state.startY = controlPos.y;
if (!MOBILE) {
$(document).bind("mousemove", move);
$(document).bind("mouseup", end);
} else {
$(document).bind("touchmove", move);
$(document).bind("touchend", end);
}
};
!MOBILE ? target.on("mousedown", start) : target.on("touchstart", start);
}
});
复制代码
转载于:https://juejin.im/post/5a8159095188257a804a945e