这文章是我自己的学习记录,若文中有理解有误的地方,请在评论区指出,我再理解一下,更快进步,非常感谢!
- 直接上代码
//(我们的每个实例身上已经在down方法中携带了,但是在不同的作用域,需要使用实例对象将其联系起来,因为两者的this都是指向实例化对象的,故this.可以访问mouseToEle)
function Drag(ele){
//封装了一个拖拽的构造函数,只要是new构造调用的实例就可以使用其中的特权方法,公有属性和方法
//每一个new的实例元素都会被获取,故这是它们的公有属性,使用this.ele释放给实例对象,ele可以是id,标签名等
this.ele = document.querySelector(ele);
//每一个实例对象都要有点击按下的事件,故使用this进行释放这个特权方法,这个方法就是实例对象才有权利访问
//为什么不将这个方法添加到原型对象上面去?
//因为我们需要触发这个事件,此处触发的event对象只能是鼠标所以就把它设置成一个特权属性而不是一个公有属性,实例对象的特权方法,它们各自有自己的内存空间,只是它们长得'一样'罢了. 记得将mouse事件对象传入
this.ele.onmousedown = function(e){
//让每个实例对象执行它们的特权方法down(e)并传入参数
//但是显然此时我们在一个新的作用域中,这个函数的this指向与外边的显然不同,但是我要让实例对象去调用这个公有方法,这样的话需要改变this的指向,这时候可以选择链式调用bind(this)绑定也可以使用变量接收,形成闭包,直至内层函数执行完毕再断开内层函数对外层变量的引用
//使用bind的好处就是不会形成闭包,这样减少内存泄漏的风险
this.down(e);
}.bind(this);
}
//特权方法,要将参数进行接收
Drag.prototype.down = function(e){
//这里比较有趣,我们先想一下对于任何一个实例对象,鼠标到盒子的距离当你在点击按下的时候已经获取到了,而且在本次按下释放之前,这个值是个恒定值,(你移动也不会改变,鼠标和盒子的相对位移是恒定的哦)只是每个实例的具体数据有差异而已,所以可以将这个属性设置成一个公有属性,这样的话所有的实例调用down方法的或获取到自己值便于计算元素的实际位移
//注意的是offsetX和offsetY是鼠标到文档边缘的横纵向