javascript 拖拽


// 先声明一个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()

猜你喜欢

转载自blog.csdn.net/Wang_x_y_/article/details/121750569
今日推荐