1. 前言
在上一篇文章中,已经实现了拖拽的效果,但并不利用复用,我们使用面向对象的方式,将代码重构一遍。
2. 代码
(function() {
function Drag(selector) {
// 传进来的如果是DOM对象则不用再查找
this.elem = typeof selector == 'object' ? selector : document.querySelector(selector)
// 鼠标在盒子内部的偏移
this.innerDis = {}
this.init()
}
Drag.prototype = {
constructor: Drag,
init: function() {
this.handleDrag()
},
getStyle: function(){
return window.getComputedStyle(this.elem, null)
},
getTargetPos: function() {
var elemStyle = this.getStyle()
var pos = {
x: parseInt(elemStyle.left.slice(0, -2)),
y: parseInt(elemStyle.top.slice(0, -2))
}
return pos
},
setTargetPos: function(pos) {
this.elem.style.left = pos.x
this.elem.style.top = pos.y
return this.elem
},
handleDrag: function() {
var self = this
function start(event) {
var divPos = self.getTargetPos()
// 鼠标按下的时候,记录鼠标在div内部的距离
var innerDis = {
x: event.clientX - divPos.x,
y: event.clientY - divPos.y
}
self.innerDis = innerDis
// 注意必须绑定在document对象上,如果绑定在box对象上,当鼠标脱快了移出box盒子时,就会产生BUG
document.addEventListener('mousemove', move, false)
document.addEventListener('mouseup', end, false)
}
function move(event) {
// 拖动元素的新位置 = 鼠标移动到的新位置 - 鼠标在div的内部距离
var pos = {
x: (event.clientX - self.innerDis.x) + 'px',
y: (event.clientY - self.innerDis.y) + 'px',
}
self.setTargetPos(pos)
}
function end() {
document.removeEventListener('mousemove', move)
document.removeEventListener('mouseup', end)
}
this.elem.addEventListener('mousedown', start)
}
}
window.Drag = Drag
})()
new Drag('.box')
还可以写成jquery插件的形式
添加上代码
(function ($) {
$.fn.extend({
becomeDrag: function () {
new Drag(this[0]);
return this; // 保证链式访问
}
})
})(jQuery);
$('.box').becomeDrag()