拖动

作者: sweetBoy_9126 | 来源:发表于2019-01-24 22:46 被阅读13次

    实现思路:首先需要点击后开始拖动,也就是给一个变量mousedown的时候为true,mouseup的时候为false,然后在mousemove的时候判断这个变量是否存在,需要鼠标点击当前元素的任何一个位置得到当前这个点距当前元素最左边和最上边的距离(需要拖动元素的e.clientX-需要拖动元素的.offsetLeft),然后拖动的时候通过监听document里的clientX/clientY-你刚才得到的距左边/顶部的距离拿到的这个差值就是你需要设置的left和top值,而且重要的一点除了mousedown是监听的需要拖动的元素外,其他的mousemove和mouseup监听的都必须是document
    另外为了让手机也使用你也同时需要监听touchstart、touchmove、touchend

    1.在mousedown的时候拿到你当前点距当前元素的距离


    2.在mousemove移动后通过e.clientX/e.clientY-上面获取到的距离就是我们的left/top的值


    案例1:拖拽弹窗

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>拖拽</title>
      <style>
        body{
          height: 100vh;
          width: 100%;
          overflow: hidden;
        }
        *{
          margin: 0;
        }
        .box{
          width: 200px;
          height: 200px;
          background: red;
          position: absolute;
        }
      </style>
    </head>
    <body>
    <div class="box"></div>
      <script>
    {
        let view = {
            el: '.box',
            init(){
                this.box = document.querySelector(this.el)
                this.document = document
            }
        }
        let controller = {
            moving: false,
            init(view){
                this.view = view
                this.view.init()
                this.bindEvent()
            },
            preventDefaultEvent(){
                // 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
                if (this.event && this.event.preventDefault) {
                    this.event.preventDefault();
                } else {
                    this.event.returnValue = false;
                }
                // 禁止事件冒泡
                if (this.event && this.event.stopPropagation) {
                    this.event.stopPropagation();
                } else {
                    window.event.cancelBubble = true;
                }
            },
            touchOrMouse(){
                this.clientEvent = this.event.touches ? this.event.touches[0] : this.event
                this.clientX = this.clientEvent.clientX
                this.clientY = this.clientEvent.clientY
            },
            down(e){
                this.moving = true
                this.event = e || window.event
                // 要同时适配mousedown和touchstart事件
                this.touchOrMouse()
                this.left = this.clientX - this.view.box.offsetLeft
                this.top = this.clientY - this.view.box.offsetTop
                this.preventDefaultEvent()
            },
            move(e){
                this.event = e || window.event
                if(this.moving){
                    this.touchOrMouse()
                    this.left1 = this.clientX - this.left
                    this.top1 = this.clientY - this.top
                    this.view.box.style.left = `${this.left1}px`
                    this.view.box.style.top = `${this.top1}px`
                }
            },
            end(e){
                this.moving = false
            },
            bindEvent(){
                this.view.box.addEventListener('mousedown',this.down.bind(this))
                this.view.box.addEventListener('touchstart',this.down.bind(this))
                this.view.document.addEventListener('mousemove',this.move.bind(this))
                this.view.document.addEventListener('touchmove',this.move.bind(this))
                this.view.document.addEventListener('mouseup',this.end.bind(this))
                this.view.document.addEventListener('touchend',this.end.bind(this))
            }
        }
        controller.init(view)
    }
    
    
      </script>
    </body>
    </html>
    

    案例2:进度条拖拽

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                display: flex;
            }
            .progress-wrapper{
                position: relative;
                height: 3vh;
                background: #ccc;
                flex: 1;
                margin: 40px;
            }
            .progress-bg,.progress-dot{
                position: absolute;
                left: 0;
            }
            .progress-bg{
                height: 100%;
                background: green;
            }
            .progress-dot{
                height: 6vh;
                width: 12px;
                background: green;
                top: 50%;
                transform: translateY(-50%);
            }
        </style>
    </head>
    <body>
        <div class="progress-wrapper">
            <div class="progress-bg"></div>
            <div class="progress-dot"></div>
        </div>
        <script>
            {
                let view = {
                    el: '.progress-wrapper',
                    init(){
                        this.box = document.querySelector(this.el)
                        this.bg = this.box.children[0]
                        this.dot = this.box.children[1]
                    }
                }
                let controller = {
                    moving: false,
                    document: null,
                    init(view){
                        this.view = view
                        this.view.init()
                        this.document = document
                        this.bindEvent()
                    },
                    preventDefaultEvent(){
                        // 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
                        if (this.event && this.event.preventDefault) {
                            this.event.preventDefault();
                        } else {
                            this.event.returnValue = false;
                        }
                        // 禁止事件冒泡
                        if (this.event && this.event.stopPropagation) {
                            this.event.stopPropagation();
                        } else {
                            window.event.cancelBubble = true;
                        }
                    },
                    touchOrMouse(){
                        this.clientEvent = this.event.touches ? this.event.touches[0] : this.event
                        this.clientX = this.clientEvent.clientX
                    },
                    down(e){
                        this.moving = true
                        this.event = e || window.event
                        this.touchOrMouse()
                        this.left = this.clientX - this.view.dot.offsetLeft
                    },
                    move(e){
                        this.event = e || window.event
                        this.touchOrMouse()
                        if(this.moving){
                            this.left1 = this.clientX -this.left
                            this.view.dot.style.left = `${this.left1}px`
                            this.view.bg.style.width = `${this.left1}px`
                        } 
                    },
                    end(e){
                        this.moving = false
                    },
                    bindEvent(){
                        this.view.dot.addEventListener('mousedown',this.down.bind(this))
                        this.view.dot.addEventListener('touchstart',this.down.bind(this))
                        this.document.addEventListener('mousemove',this.move.bind(this))
                        this.document.addEventListener('touchmove',this.move.bind(this))
                        this.document.addEventListener('mouseup',this.end.bind(this))
                        this.document.addEventListener('touchend',this.end.bind(this))
                    }
                }
                controller.init(view)
            }
        </script>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:拖动

          本文链接:https://www.haomeiwen.com/subject/nzqpjqtx.html