zoukankan      html  css  js  c++  java
  • 拖拽滚动视图(一)

    鼠标拖拽

    事件

    container.addEventListener("touchstart", dragStart, false);// 进入
    container.addEventListener("touchend", dragEnd, false); // 离开
    container.addEventListener("touchmove", drag, false); // 移动
    
    container.addEventListener("mousedown", dragStart, false); // 进入
    container.addEventListener("mouseup", dragEnd, false); // 离开
    container.addEventListener("mousemove", drag, false);// 移动
    

    Element.getBoundingClientRect()

    返回元素的大小及其相对视口的位置,以css设置宽高作为衡量准备

    offset(只读)

    Element.offsetWidth css宽度,包括border,padding,scrollbar(水平滚动条),width

    Element.offsetHeight css 高度,包括 border,padding,scrollbar(垂直滚动条),height

    Element.offsetLeft 左边的偏移值

    Element.offsetTop 距离顶部的偏移值

    Element.offsetParent

    • 如果父级有定位,返回带有定位的父级dom
    • 如果父级没有定位,返回body

    client(只读)

    可视区域

    MouseEvent.clientWidth 元素内部宽度(包括padding,不包括scrollBar,border,margin)

    MouseEvent.clientHeight 元素内部高度(包括padding,不包括scrollBar,border,margin)

    MouseEvent.clientX 鼠标距离可视区域左边的距离

    MouseEvent.clientY ... 上边的距离

    Element.clientTop dom 上边框(border)的宽度

    Element.clientLeft dom 左边框(border)的宽度

    scroll

    距离: 可视区域+滚动隐藏的部分

    Element.scrollTop 读取设置, 距离顶部的距离

    Element.scrollLeft 读取设置, 距离元素left的距离

    拖拽效果

    代码映射结构

     // 按下
      box.onmousedown = function (event) {
        console.log(1);
        // 移动
        box.onmousemove=function () {
          console.log(2);
        }
        // 抬起
        box.onmouseup=function () {
          console.log(3);
        }
      }
    

    逻辑

    • 鼠标按下,获取鼠标点击时获取相对位置
    • 鼠标移动,元素的位置=鼠标的位置-刚刚的差值
    • 鼠标放下,给鼠标移动和鼠标放下设置为null
      <style>
        .box {
           100%;
          height: 80vh;
          /*display: flex;*/
          /*justify-content: center;*/
          /*align-items: center;*/
          position: relative;
          border: 2px solid red;
        }
    
        .aaa {
          position: absolute;
           50px;
          height: 50px;
          background-color: rgb(245, 230, 99);
          border: 10px solid rgba(136, 136, 136, .5);
          border-radius: 50%;
        }
    
        .aaa:hover {
          cursor: pointer;
          border- 20px;
        }
    
        .aaa:active {
          background-color: rgba(168, 218, 220, 1.00);
        }
      </style>
    
    <div class="box" id="box">
      <div id="ccc" class="aaa"></div>
    </div>
    
    <script>
      /* mousedown 鼠标进入
      *  mousemove 鼠标移动
      *  mouseup 鼠标离开
      * */
      let ccc = document.querySelector("#ccc");
      let box = document.querySelector("#box");
    
      // 按下
      ccc.onmousedown = function (event) {
    
        let x = event.clientX - this.offsetLeft
        let y = event.clientY - this.offsetTop
        // 移动
        document.onmousemove = function (e) {
          ccc.style.left = e.pageX - x + 'px';
          ccc.style.top = e.pageY - y + 'px';
        }
        // 抬起
        document.onmouseup = function () {
          document.onmousemove = null;
          document.onmouseup = null;
        }
      }
    </script>
    

    拖拽范围限制

     /* mousedown 鼠标进入
      *  mousemove 鼠标移动
      *  mouseup 鼠标离开
      * */
      let box = document.querySelector("#box");
      let ccc = document.querySelector("#ccc");
    
      ccc.onmousedown = function (event) {
        // 子盒子
        let w = ccc.getBoundingClientRect().width / 2;
        let h = ccc.getBoundingClientRect().height / 2;
        // 大盒子-小盒子
        let width = box.getBoundingClientRect().width - w;
        let height = box.getBoundingClientRect().height - h;
        // 按下的位置距离左侧的差值
        let x = event.clientX - this.offsetLeft
        let y = event.clientY - this.offsetTop
        // 移动
        document.onmousemove = function (e) {
          // 移动的坐标-左侧的坐标=子盒子的坐标
          let x1 = e.pageX - x
          let y1 = e.pageY - y;
          if (-w < x1 && x1 < width) {
            ccc.style.left = x1 + 'px';
          }
          if (-h < y1 && y1 < height) {
            ccc.style.top = y1 + 'px';
          }
        }
        // 抬起
        document.onmouseup = function () {
          document.onmousemove = null;
          document.onmouseup = null;
        }
      }
    

    我们发现出现滚动条的一些问题

    发现了会出现,滚动条的bug, 那肯定是有些东西被隐藏点了

    滚动条隐藏的解决方案

    document.documentElement.scrollTop
    window.pageYOffset
    

    如果是对应的子盒子出现了滚动条,可以在对应的添加

    关键代码修改

      // 按下的位置距离左侧的差值
        let x =(window.pageXOffset+ event.clientX) - this.offsetLeft
        let y = (window.pageYOffset+event.clientY) - this.offsetTop
    

    思考如何让视图跟着拖拽移动呢

    首先理解一个比较基础的问题

    滚动的长度 scrollTop

    scrollHeight=scrollTop+clientHeight

    同理

    scrollWidth=scrollLeft+clientWidth

    scrollLeft的距离其实就是等于:里面大盒子的长度- 视口的长度

    scrollLeft就是相当于移动的距离

    科普: 滚动的相对距离

    scrollBy(x,y) x和y指定滚动的相对量

    案例

    整体逻辑就一句话

    移动的距离/总移动的距离=鼠标移动的距离/总长度

    具体点就是

    滚动条移动的距离/滚动条移动的总距离=鼠标移动的比较/总盒子可以移动的距离

    上代码

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        * {
          margin: 0;
          padding: 0;
        }
    
        .box-over {
           60%;
          height: 60vh;
          overflow: auto;
        }
    
        .box {
           140%;
          height: 150vh;
          margin: 200px auto;
          position: relative;
          border: 2px solid red;
        }
    
        .aaa {
          position: absolute;
           50px;
          height: 50px;
          background-color: rgb(245, 230, 99);
          border: 10px solid rgba(136, 136, 136, .5);
          border-radius: 50%;
        }
    
        .aaa:hover {
          cursor: pointer;
          border- 20px;
        }
    
        .aaa:active {
          background-color: rgba(168, 218, 220, 1.00);
        }
      </style>
    </head>
    <body>
    <div class="box-over">
      <div class="box" id="box">
        <div id="ccc" class="aaa"></div>
      </div>
    </div>
    
    
    <script>
      /* mousedown 鼠标进入
      *  mousemove 鼠标移动
      *  mouseup 鼠标离开
      * */
      let box = document.querySelector("#box");
      let ccc = document.querySelector("#ccc");
      let over = document.querySelector('.box-over');
      ccc.onmousedown = function (event) {
        //计算大盒子内部的宽高
        let overW = box.getBoundingClientRect().width;
        let overH = box.getBoundingClientRect().height;
        //大盒子滚动条移动的距离
        let overs = {
          x: over.scrollWidth - over.clientWidth,
          y: over.scrollHeight - over.clientHeight,
        }
        // 子盒子
        let w = ccc.getBoundingClientRect().width / 2;
        let h = ccc.getBoundingClientRect().height / 2;
        // 大盒子-小盒子
        let width = box.getBoundingClientRect().width - w;
        let height = box.getBoundingClientRect().height - h;
        // 按下的位置距离左侧的差值
        let x = (window.pageXOffset + event.clientX) - this.offsetLeft
        let y = (window.pageYOffset + event.clientY) - this.offsetTop
        // 移动
        document.onmousemove = function (e) {
          // 移动的坐标-左侧的坐标=子盒子的坐标
          let x1 = e.pageX - x
          let y1 = e.pageY - y;
    
          if (-w < x1 && x1 < width) {
            ccc.style.left = x1 + 'px';
          }
          if (-h < y1 && y1 < height) {
            ccc.style.top = y1 + 'px';
          }
          // 移动的距离/总距离=鼠标移动的距离/总长度
          // 滚动条移动的距离/滚动条移动的总距离=鼠标移动的比较/总盒子可以移动的距离
          over.scrollLeft = x1 / overW * overs.x
          over.scrollTop = y1 / overH * overs.y
        }
        // 抬起
        document.onmouseup = function () {
          document.onmousemove = null;
          document.onmouseup = null;
        }
      }
    </script>
    </body>
    </html>
    

    决定自己的高度的是你的态度,而不是你的才能

    记得我们是终身初学者和学习者

    总有一天我也能成为大佬

  • 相关阅读:
    算法:二分图最大独立集
    算法:桶排序
    算法:二分图最小点覆盖——Konig定理
    jQuery基础整理之思维导图
    vue基础知识整理
    HTML总结
    JAVAScript总结
    栈和队列
    今日学习遇到的问题(2018.9.23)
    看了vue文档之后。。。。
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/13878431.html
Copyright © 2011-2022 走看看