zoukankan      html  css  js  c++  java
  • JS鼠标的拖拽原理

    一、拖拽的流程动作
    ①鼠标按下
    ②鼠标移动
    ③鼠标松开

    二、鼠标按下事件

    ①鼠标按下会触发onmousedown事件

     var self = this;
                self.elements.addEventListener("mousedown",start,false)
              
                }

    ②鼠标移动会触发onmousemove事件

     document.addEventListener("mousemove",move,false)

    ③鼠标松开会触发onmouseup事件

    document.addEventListener("mouseup",end,false)

    三、实现的原理讲解
    拖拽其实是通过获取鼠标移动的距离来实现的,即计算移动前的位置的坐标(x,y)与移动中的位置的坐标(x,y)差值。
    当鼠标按下或鼠标移动时,都可以获取到当前鼠标的位置,即移动前的位置与移动中的位置。
    那么上面①与②的代码就应该变成这样

    var self = this;
                self.elements.addEventListener("mousedown",start,false)
                function start(event) {
              //鼠标按下时的鼠标所在的X,Y坐标   self.startX
    = event.pageX; // srarX,startY 应该要全局,因为 鼠标移动过程需要计算鼠标按下时的坐标 self.startY = event.pageY;
              //初始位置的X,Y 坐标   self.sourceX
    = self.getStyle("left"); self.sourceY = self.getStyle("top"); document.addEventListener("mousemove",move,false) document.addEventListener("mouseup",end,false) }
    function move(event) {
    var currentX = event.pageX;
    var currentY = event.pageY;
    var width = document.documentElement.clientWidth ;
    var height = document.documentElement.clientHeight;
    var x = (event.clientX-self.startX);
    var y = (event.clientY-self.startY);
    if (x < 0) {
    x = 0
    } else if (x > width-self.getStyle("width")){
    x = width-self.getStyle("width")
    }
    if (y<0){
    y = 0
    }else if (y > height - self.getStyle("height")){
    y =height- self.getStyle("height")
    }

    self.setPosition({
    x: (x)+self.sourceX ,
    y:(y)+self.sourceY
    })
    }
    移动前与移动后坐标有了,那么计算偏移,先看下图(网络图,侵权删)
    
    

     很明显移动后元素的X坐标为  鼠标移动后的X坐标 - 鼠标按下的X坐标 + 元素的初始X坐标
    Y坐标为  鼠标移动后的Y坐标 - 鼠标按下的Y坐标 + 元素的初始Y坐标
    把新的 X,Y 替换元素的 X,Y 就搞定了。
    那么代码就应该更换为:

    var self = this;
                self.elements.addEventListener("mousedown",start,false)
                function start(event) {
                    self.startX = event.pageX;
                    self.startY = event.pageY;
                    self.sourceX = self.getStyle("left");
                    self.sourceY = self.getStyle("top");
                    document.addEventListener("mousemove",move,false)
                    document.addEventListener("mouseup",end,false)
                }
                function move(event) {
                    var currentX = event.pageX;
                    var currentY = event.pageY;
                    var width = document.documentElement.clientWidth ;
                    var height = document.documentElement.clientHeight;
                    var x = (event.clientX-self.startX);
                    var y = (event.clientY-self.startY);
                    if (x < 0) {
                        x = 0
                    } else if (x > width-self.getStyle("width")){
                        x = width-self.getStyle("width")
                    }
                    if (y<0){
                        y = 0
                    }else if (y > height - self.getStyle("height")){
                        y =height- self.getStyle("height")
                    }
    
                    self.setPosition({
                        x: (x)+self.sourceX ,
                        y:(y)+self.sourceY
                    })
                }
                function end() {
                    document.removeEventListener('mousemove', move);
                    document.removeEventListener('mouseup', end);
                }
            },
            setPosition:function (pos) {
                // console.log(pos.x,pos.y)
                this.elements.style.transform = "translate(" + pos.x + "px, " + pos.y + "px)"
            }
    
    
    
     

    整体代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            #drag{
                 100px;
                height: 100px;
                background: #333;
            }
            *{
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
    <body>
    <div id="drag"></div>
    <script>
        /**
         * @file: drag.html
         * @method Drag
         * @param {Object} option - 对象 非必传 不传回创建一个div作为拖拽的对象
         * @description:
         * @author: 
         * @date: 2019/12/14 12:31
         */
        function Drag(option) {
            if (typeof option === "object") {
                this.elements = option.drag;
            } else{
                this.elements = document.createElement("div");
                this.elements.style.width = "100px";
                this.elements.style.height = "100px";
                this.elements.style.backgroundColor = "#000";
                this.elements.setAttribute("class","drag");
                document.body.appendChild(this.elements)
            }
    
            this.startX = 0;
            this.startY = 0;
            this.sourceX = 0;
            this.startY = 0;
            this.init()
    
        }
        Drag.prototype = {
            /*
            * 初始化需要绑定事件
            * */
            constructor:Drag,
            init:function () {
                this.bindEvent();
            },
            /*
            * 获取当前拖拽元素的距离上,下位置
            * @returns {number}
            * */
            getStyle:function(property){
               // return document.defaultView.getComputedStyle(this.elements)[property]
                return this.elements.getBoundingClientRect()[property]
            },
            /*
            *绑定拖拽的元素,移动和鼠标松开后是对document的绑定,因为移动的是整个div
            *
            * */
            bindEvent:function () {
                var self = this;
                self.elements.addEventListener("mousedown",start,false)
                function start(event) {
                    self.startX = event.pageX;
                    self.startY = event.pageY;
                    self.sourceX = self.getStyle("left");
                    self.sourceY = self.getStyle("top");
                    document.addEventListener("mousemove",move,false)
                    document.addEventListener("mouseup",end,false)
                }
                function move(event) {
                    var currentX = event.pageX;
                    var currentY = event.pageY;
                    var width = document.documentElement.clientWidth ;
                    var height = document.documentElement.clientHeight;
                    var x = (event.clientX-self.startX);
                    var y = (event.clientY-self.startY);
                    if (x < 0) {
                        x = 0
                    } else if (x > width-self.getStyle("width")){
                        x = width-self.getStyle("width")
                    }
                    if (y<0){
                        y = 0
                    }else if (y > height - self.getStyle("height")){
                        y =height- self.getStyle("height")
                    }
    
                    self.setPosition({
                        x: (x)+self.sourceX ,
                        y:(y)+self.sourceY
                    })
                }
                function end() {
                    document.removeEventListener('mousemove', move);
                    document.removeEventListener('mouseup', end);
                }
            },
            setPosition:function (pos) {
                // console.log(pos.x,pos.y)
                this.elements.style.transform = "translate(" + pos.x + "px, " + pos.y + "px)"
            }
        }
        new Drag({
            drag:document.querySelector("#drag")
        })
    </script>
    </body>
    </html>

    如有不正确之处欢迎大家指正

    原文:https://www.cnblogs.com/yangguoe/p/8527264.html

  • 相关阅读:
    javascript延迟对象
    Fetch-新一代Ajax API
    AJAX笔记
    VR/AR/MR
    为什么Javascript有设计缺陷
    Javascript函数式编程
    vim基本操作
    Git 常用命令(二)
    SSH配置
    C# NPOI导出Excel和EPPlus导出Excel
  • 原文地址:https://www.cnblogs.com/yangwenbo/p/12053483.html
Copyright © 2011-2022 走看看