// 先声明一个that 变量 用来存储this
var that;
var position = 0
// 使用 ES6的 class 类 声明一个类
class createDrag {
// constructor 是必须有的
constructor(options) {
// options 接收的参数
// 给this上挂载一个domData 利用Object.assign 把options 来合并
// 意思就是 如果options 没有传相对应需要的值 就把默认的合并的给它
position == 0 ? position += 10 : position
this.domData = Object.assign({
height: '150px',
width: '150px',
left: position + 'px',
top: '10px',
background: 'red',
zIndex: '999',
position: 'fixed',
borderRadius: '50%'
}, options)
position += Number(this.domData.width.replace('px', "")) + 10
//用来接收 鼠标于屏幕最左边的距离
// x就是横向
this.startX = 0
// y就是竖向/纵向
//用来接收 鼠标于屏幕最顶部的距离
this.startY = 0
//先创建个divDOM元素
this.dom = document.createElement('div')
//调用原型上的createDom()函数
this.createDom()
//先把this赋值给that 用于后期方便解决this指向的问题
that = this
}
// 初始化创建的DOM
createDom() {
/* 先初始化一下样式
就是把this.domData的key值写为跟操作dom的style对象里的key值一样
简洁化写 因为这俩对象key值也就是键值都一样 所以可以用for in 遍历该对象 key键值公用
*/
for (let key in this.domData) {
this.dom.style[key] = this.domData[key]
}
// this.dom.style.borderRadius = this.domData.borderRadius
// this.dom.style.left = this.domData.left
// this.dom.style.position = this.domData.options
// this.dom.style.top = this.domData.top
// this.dom.style.height = this.domData.height
// this.dom.style.zIndex = this.domData.z_index
// this.dom.style.width = this.domData.width
// this.dom.style.background = this.domData.bgColor
//把初始化好的DOM元素添加到body里
document.body.append(this.dom)
// 如果想加到别的元素里可以使用 appendChild 来追加进去
// document.getElementById("元素的id").appendChild(this.dom)
//调用原型上mouseDown()
this.mouseDown()
}
//用来执行事件创建的DOM的鼠标按下事件
mouseDown() {
this.dom.onmousedown = (e) => {
// e.clientX 鼠标离可视区域左上角的X坐标
// e.clientY 鼠标离可视区域左上角的Y坐标
// e.target.offsetLeft 是返回事件源跟距离最近具有定位父元素的左边距离
// e.target.offsetTop 是返回事件源跟距离最近具有定位父元素的顶边距离
// startX可以保存鼠标刚按下时的在元素内X位置
// startY可以保存鼠标刚按下时的在元素内Y位置
this.startX = e.clientX - e.target.offsetLeft;
this.startY = e.clientY - e.target.offsetTop
this.mouseMove()
this.mouseUp()
}
}
// 因为元素是在顶级元素document上进行鼠标滑动的 所以直接给document绑定鼠标滑动事件即可
//也可以给this.dom 绑定 不过滑的速度不能太快 容易丢失
mouseMove() {
document.onmousemove = (ev) => {
ev.preventDefault()
// x就是元素最终减去鼠标刚按下时的在元素内X位置
// y就是元素最终减去鼠标刚按下时的在元素内Y位置
//从而得到鼠标在元素内位置不变 且能改变元素的X、Y轴的定位
let x = ev.clientX - this.startX;
let y = ev.clientY - this.startY;
// 最终赋值给元素
this.dom.style.left = x + 'px'
this.dom.style.top = y + 'px'
}
}
// 用来执行元素鼠标的弹起事件
mouseUp() {
document.onmouseup = () => {
// 用谁执行的鼠标移动事件 就把谁的onmouseove给为空
document.onmousemove = null
// this.dom.onmousemove = null
}
}
}
// 利用ES6的语法糖 class 再创建一个类对象 使用 extends 继承 父 createDrag 的原生方法和数据
class viceCreateDrag extends createDrag {
constructor(options) {
//这里的options 是用new 关键字 调用viceCreateDrag 时传的参数
/* 想要使用constructor的话
必须用 super()调用一下 可以传递参数 就能传递到父元素的constructor的函数里
*/
super(options)
}
// 自己的方法 跟父级里的函数名字一样的话 如果继承的父级里有调用 就会调用这个 会代替掉父级的那个
mouseMove() {
document.onmousemove = (ev) => {
ev.preventDefault()
// x就是元素最终减去鼠标刚按下时的在元素内X位置
// y就是元素最终减去鼠标刚按下时的在元素内Y位置
//从而得到鼠标在元素内位置不变 且能改变元素的X、Y轴的定位
let x = ev.clientX - this.startX;
let y = ev.clientY - this.startY;
// 如果小于0的话就直接等于0 用来限制位置 不能拖出视图窗口
// 这样只能判断 左边和上边
x = x < 0 ? 0 : x
y = y < 0 ? 0 : y
// 这样可以判断 右边和下边
// document.documentElement.clientWidth 是获取到 顶级对象dom的内容宽度 不算边框
// document.documentElement.clientHeight 是获取到 顶级对象dom的内容高度 不算边框
// this.dom.offsetWidth 获取当前拖动dom的 宽度包含边框
// this.dom.offsetHeight 获取当前拖动dom的 高度度包含边框
/*
document.documentElement.clientWidth - this.dom.offsetWidth
就能求出右边的最大距离 如果大于这个距离说明已经超出了 只能让它等于这个最大距离即可
document.documentElement.clientHeight - this.dom.offsetHeight
就能求出下边的最大距离 如果大于这个距离说明已经超出了 只能让它等于这个最大距离即可
*/
x = x > document.documentElement.clientWidth - this.dom.offsetWidth ? document.documentElement.clientWidth - this.dom.offsetWidth : x
y = y > document.documentElement.clientHeight - this.dom.offsetHeight ? document.documentElement.clientHeight - this.dom.offsetHeight : y
this.dom.style.left = x + 'px'
this.dom.style.top = y + 'px'
}
}
}
new viceCreateDrag({ background: 'Yellow' })
new viceCreateDrag({ background: 'blue' })
new createDrag()
javascript 拖拽
猜你喜欢
转载自blog.csdn.net/Wang_x_y_/article/details/121750569
今日推荐
周排行