• 25vue中实现拖动调整左右两侧盒子的宽度


    这里是直接完整一个组件,路由引入即可看到效果。

    <template>
      <div class="box" ref="box">
        <div class="left">
          <!--左侧div内容-->
          <h1>到了时间你就一定要上场</h1>
          <h1>当意识到达,那就必须上岸</h1>
        </div>
        <div class="resize" title="收缩侧边栏"></div>
        <div class="mid">
          <!--右侧div内容-->
          <h1>我希望我希望的有希望</h1>
          <h1>想着光向着光</h1>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {};
      },
      methods: {
        dragControllerDiv() {
          var resize = document.getElementsByClassName("resize")[0];
          var left = document.getElementsByClassName("left");
          var mid = document.getElementsByClassName("mid");
          var box = document.getElementsByClassName("box")[0];
    
          // 鼠标按下事件
          resize.onmousedown = function (e) {
            //颜色改变提醒
            resize.style.background = "#818181";
            var startX = e.clientX;
            resize.left = resize.offsetLeft;
            // 鼠标拖动事件
            document.onmousemove = function (e) {
              var endX = e.clientX;
              var moveLen = resize.left + (endX - startX); // (endx-startx)=移动的距离。resize.left+移动的距离=左边区域最后的宽度
              var maxT = box.clientWidth - resize.offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
    
              if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
              if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
    
              resize.style.left = moveLen; // 设置左侧区域的宽度
    
              for (let j = 0; j < left.length; j++) {
                left[j].style.width = moveLen + "px";
                mid[j].style.width = box.clientWidth - moveLen - 10 + "px";
              }
            };
            // 鼠标松开事件
            document.onmouseup = function () {
              //颜色恢复
              resize.style.background = "#d6d6d6";
              document.onmousemove = null;
              document.onmouseup = null;
              resize.releaseCapture && resize.releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
            };
            resize.setCapture && resize.setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
            return false;
          };
        },
      },
      mounted() {
        this.dragControllerDiv();
      },
    };
    </script>
    
    <style scoped>
    /* 拖拽相关样式 */
    /*包围div样式*/
    .box {
       100%;
      height: 50vh;
      margin: 5vh 0px;
      overflow: hidden;
      box-shadow: -1px 9px 10px 3px rgba(0, 0, 0, 0.11);
    }
    /*左侧div样式*/
    .left {
       calc(32% - 10px); /*左侧初始化宽度*/
      height: 100%;
      background: #ffffff;
      float: left;
    }
    /*拖拽区div样式*/
    .resize {
      cursor: col-resize;
      float: left;
      position: relative;
      top: 45%;
      background-color: #d6d6d6;
      border-radius: 5px;
      margin-top: -10px;
       10px;
      height: 50px;
      background-size: cover;
      background-position: center;
      /*z-index: 99999;*/
      font-size: 32px;
      color: white;
    }
    /*拖拽区鼠标悬停样式*/
    .resize:hover {
      color: #444444;
    }
    /*右侧div'样式*/
    .mid {
      float: left;
       68%; /*右侧初始化宽度*/
      height: 100%;
      background: #fff;
      box-shadow: -1px 4px 5px 3px rgba(0, 0, 0, 0.11);
    }
    </style>

     左侧如果有ifame,解决方案参考


    封装好的组件:(vue文件)

    <template>
      <div id="dragLayoutBox">
        <div class="left_box">
          <slot name="left-content"></slot>
        </div>
        <div class="right_box">
          <div v-if="iframeIsHave" class="opacity_box"></div>
          <div
            v-show="dragBtnFlag"
            class="drag_btn"
            @mousedown="changeBoxStyleFn('')"
            @onmouseup="changeBoxStyleFn('none')"
          ></div>
          <slot name="right-content"> </slot>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        // 是否默认显示拖拽按钮
        dragBtnFlag: {
          typeof: Boolean,
          default: true
        },
        // 盒子中是否有iframme
        iframeIsHave: {
          typeof: Boolean,
          default: false
        },
        // 配置项 注意:色值暂时只支持16进制写法
        setCssProps: {
          typeof: Object,
          default: () => ({
            // 左右盒子最小拖动宽度
            leftMinWidth: '200px',
            rightMinWidth: '500px',
            dragBtnCss: {
              mousedown: {
                background: '#919191'
              },
              onmouseup: {
                background: '#d6d6d6'
              }
            }
          })
        }
      },
      mounted() {
        if (this.iframeIsHave) {
          this.changeBoxStyleFn('none')
        }
        this.dragChangeLayoutFn()
      },
      methods: {
        getDomFn(name) {
          const ele = document.querySelector(name)
          const ws = new WeakSet()
          ws.add(ele)
          return ele
        },
        changeBoxStyleFn(value) {
          if (this.iframeIsHave) {
            const opacityBox = this.getDomFn('.opacity_box')
            opacityBox.style.display = value
          }
        },
        dragChangeLayoutFn() {
          const that = this
          const dragBtn = this.getDomFn('.drag_btn')
          const left_box = this.getDomFn('.left_box')
          const right_box = this.getDomFn('.right_box')
          const dragLayoutBox = this.getDomFn('#dragLayoutBox')
          dragBtn.onmousedown = function (e) {
            const styleStr = that.handleEleStyleFn(that.setCssProps.dragBtnCss.mousedown)
            dragBtn.style.cssText = `${styleStr}`
            const startPos = e.clientX
            dragBtn.left = dragBtn.offsetLeft
            document.onmousemove = e => {
              const endPos = e.clientX
              let moveW = dragBtn.left - 20 + (endPos - startPos)
              const maxW = dragLayoutBox.clientWidth - dragBtn.offsetWidth
              // 左边区域的最小宽度
              const leftValue = parseInt(that.setCssProps.leftMinWidth)
              if (moveW < leftValue) {
                moveW = leftValue
              }
              // 右边区域最小宽度
              const rightValue = parseInt(that.setCssProps.rightMinWidth)
              if (moveW > maxW - rightValue) {
                moveW = maxW - rightValue
              }
              left_box.style.cssText = `${moveW}px`
              right_box.style.width = dragLayoutBox.clientWidth - moveW + 'px'
            }
            document.onmouseup = () => {
              const styleStr = that.handleEleStyleFn(that.setCssProps.dragBtnCss.onmouseup)
              dragBtn.style.cssText = `${styleStr}`
              document.onmousemove = document.onmouseup = null
              if (that.iframeIsHave) {
                that.changeBoxStyleFn('none')
              }
              dragBtn.releaseCapture && dragBtn.releaseCapture()
            }
            dragBtn.setCapture && dragBtn.setCapture()
            return false
          }
        },
        // 处理传来的对象:{k1:"v1",k2:"v2"} => "k1:v1;k2:v2"
        handleEleStyleFn(obj) {
          let str = JSON.stringify(obj)
          const indexstart = str.indexOf('{')
          const indexEnd = str.indexOf('}')
          str = str.slice(indexstart + 1).slice(0, indexEnd - 1)
          const reg1 = /,/g
          const reg2 = /"|'/g
          return str.replace(reg1, ';').replace(reg2, '')
        }
      }
    }
    </script>
    
    <style scoped>
    #dragLayoutBox {
       100%;
      display: flex;
      justify-content: space-between;
      box-shadow: 0px 20px 40px 0px rgba(0, 0, 0, 0.08);
    }
    .drag_btn {
      position: absolute;
      top: calc((100vh - 50px) / 2);
       8px;
      height: 50px;
      cursor: col-resize;
      background: rgba(0, 0, 0, 0.1);
      border-radius: 5px;
      margin-top: -10px;
      background-size: cover;
      background-position: center;
      font-size: 32px;
      color: white;
      z-index: 1112;
    }
    .opacity_box {
       100%;
      height: 100%;
      position: absolute;
      margin-top: 30px;
      filter: alpha(opacity=0);
      opacity: 0;
      background: transparent;
      z-index: 1111;
    }
    </style>

    使用:

    1.引入和注册

    const LayoutDrag = () => import('./LayoutDrag/index.vue')
    components: {  LayoutDrag }

    2.使用:iframeIsHave为true表示右侧区域内有iframe,默认不传则为false,这个的判定就是为了解决当有iframe(比如富文本)拖拽时卡顿问题

     <LayoutDrag :iframeIsHave="true">
        <template v-slot:left-content>
            // 你的左侧盒子的盛放区域
        </template>
    
        <template v-slot:right-content>
          // 你的右侧盒子盛放区域
        </template>
    </LayoutDrag>
  • 相关阅读:
    音频可视化
    accunulate
    node
    js 中编码(encode)和解码(decode)的三种方法
    ES6高阶 同步和异步 回调地狱 promise async和await
    区间dp
    树形dp1
    背包dp(多重)
    树形dp
    背包dp(完全)
  • 原文地址:https://www.cnblogs.com/haoqiyouyu/p/16137913.html
Copyright © 2020-2023  润新知