通过鼠标移动来调整两个盒子的宽度(响应式)

DOM结构:

html 复制代码
 <div class="courer">  // 外层盒子
      <div  class="dividing-line" title="拖动"></div>  // 拖动的那个线
      <div class="course-title-box">  // 第一个盒子
        <div class="course-content-box" v-infinite-scroll="load" infinite-scroll-disabled="disabled">
         
          <div v-for="(item2, i2) in detialList" :key="i2" @contextmenu="handleRightClick(i2, item2)">
            <!--标题-->
            <div class="course-content-item" @click="currentChange(item2)">
              <div style="width: calc(100% - 50px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
              
                {{ item2.name }}
              </div>
            </div>
          </div>
         
          <div v-if="noMore" style="color: #999; font-size: 12px; text-align: center; margin: 10px 0">没有更多了</div>
        </div>
      </div>
      <div class="course-detail-content-box" style="display: flex; align-items: center; justify-content: center">// 第二个盒子
        <div style="color: #bdbdbd">
          <span>点击任务标题查看详情</span>
        </div>
      </div>
      
    </div>

css样式:

css 复制代码
.courer {
  /* padding: 20px; */
  width: calc(100% - 150px);
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  position: relative;
}
.dividing-line {
  position: absolute;
  width: 10px;
  height: 100%;
  left: 200px;
  top: 0;
  transform: translate(-50%, 0);
  cursor: col-resize;
  /* background-color: rgba(20, 20, 23, 0.3); */
  background-color: transparent;
}

.course-title-box {
  width: 200px;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  /* background-color: #789; */
  border-right: 1px solid rgba(0, 0, 0, 0.07);
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  padding: 5px 15px;

  .course-title-item {
    cursor: pointer;
    padding: 10px 0;
    color: #333;
    font-weight: 700;
    /* background-color: #669; */
    position: relative;

    &:hover {
      color: #5fa4f6;

      .el-icon-more-outline {
        display: block;
      }
    }

    .el-icon-more-outline {
      display: none;
    }

    span {
      padding: 0 7px;
    }

    .add {
      position: absolute;
      right: 5px;
      top: 13px;
    }
  }

  .course-content-box {
    .course-content-item {
      color: #333;
      cursor: pointer;
      padding: 10px;
      /* background-color: #898; */
      border-bottom: 1px solid rgba(0, 0, 0, 0.03);
      position: relative;

      &:hover {
        background-color: #e7f3ff;
      }

      .detail-box {
        position: absolute;
        right: 13px;
        top: 0;
        height: 40px;
        display: flex;
        align-items: center;

        .more-icon:hover {
          color: #5fa4f6;
        }
      }
    }

    .active-course-content-item {
      background-color: #e7f3ff;
    }
  }
}

重中之重的js代码:

javascript 复制代码
// methods里的

    setTaskBox() {
      if (window.localStorage.getItem('lineLeft') != null) {
        const titleBox = document.getElementsByClassName('course-title-box')[0]
        const contentBox = document.getElementsByClassName('course-detail-content-box')[0]
        const line = document.getElementsByClassName('dividing-line')[0]

        line.style.left = window.localStorage.getItem('lineLeft') + '%'
        titleBox.style.width = window.localStorage.getItem('titleBoxWidth') + '%'
        contentBox.style.width = window.localStorage.getItem('contentBoxWidth') + '%'
      }
    },

    // 实现任务列表和任务详情显现区域变化功能
    changeTaskBox() {
      const titleBox = document.getElementsByClassName('course-title-box')[0]
      const contentBox = document.getElementsByClassName('course-detail-content-box')[0]
      const line = document.getElementsByClassName('dividing-line')[0]
      const box = document.getElementsByClassName('courer')[0]
      let titleBoxStyle = window.getComputedStyle(titleBox)
      let contentBoxStyle = window.getComputedStyle(contentBox)
      let boxStyle = window.getComputedStyle(box)
      console.log(titleBoxStyle.width, contentBoxStyle.width, boxStyle.width)
      // 鼠标按下事件
      line.onmousedown = e => {
        let titleBoxWidth = parseFloat(titleBoxStyle.width)
        let contentBoxWidth = parseFloat(contentBoxStyle.width)
        let boxWidth = parseFloat(boxStyle.width)

        const startX = e.clientX
        console.log('startX', startX)
        const lineLeft = line.offsetLeft
        console.log('lineLeft', lineLeft)
        // 鼠标拖动事件
        document.onmousemove = e => {
          const moveX = e.clientX
          console.log('moveX', moveX)
          // 鼠标移动距离
          let moveLen = lineLeft + moveX - startX
          moveLen = moveLen < 200 ? 200 : moveLen //左边区域最小宽度为200px
          moveLen = moveLen > boxWidth - 500 ? boxWidth - 500 : moveLen //右边区域最小宽度为500px
          line.style.left = moveLen + 'px'
          titleBox.style.width = moveLen + 'px'
          contentBox.style.width = boxWidth - moveLen + 'px'
          titleBoxWidth = parseFloat(titleBoxStyle.width)
          contentBoxWidth = parseFloat(contentBoxStyle.width)
        }
        // 鼠标松开事件
        document.onmouseup = function () {
          let newLineLeft = (parseInt(line.offsetLeft) / boxWidth).toFixed(2) * 100
          let newTitleBoxWidth = (titleBoxWidth / boxWidth).toFixed(2) * 100
          let newContentBoxWidth = (contentBoxWidth / boxWidth).toFixed(2) * 100

          window.localStorage.setItem('titleBoxWidth', newTitleBoxWidth)
          window.localStorage.setItem('contentBoxWidth', newContentBoxWidth)
          window.localStorage.setItem('lineLeft', newLineLeft)
          document.onmousemove = null
          document.onmouseup = null
        }
        return false
      }
    },

e.clientX 是一个事件对象的属性,它表示鼠标指针相对于浏览器视口(viewport)的水平位置。具体来说,e.clientX 返回鼠标指针相对于视口左边缘的 x 坐标。

mounted里的:

javascript 复制代码
  mounted() {
    this.changeTaskBox()
    this.setTaskBox()
  },

就可以完成拖动那根线,实现两边的盒子的宽度根据线的移动而变化;

offsetLeftstyle.left 在 Vue 或 JavaScript 中有不同的用途和含义:

1.offsetLeft:

  • 是一个只读属性,表示元素相对于其最近的定位祖先元素(或视口)的左边缘的距离。
  • 它返回的是一个整数,单位是像素(px)
  • 用于获取元素的当前位置,不可用于设置元素的位置

2.style.left:

  • style.left 是一个可读写属性,表示元素在 CSS 中的 left 属性值。
  • 它可以直接修改元素的位置。
  • 用于设置元素的 CSS left 属性,从而改变元素的位置。
  • 可以设置为字符串形式,如 '100px'100 + 'px'

应用场景

  • 当你需要获取元素的当前位置时,使用 offsetLeft
  • 当你需要动态改变元素的位置时,使用 style.left
相关推荐
尚梦32 分钟前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子1 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山1 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享2 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄3 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf4 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨4 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL4 小时前
npm入门教程1:npm简介
前端·npm·node.js
小白白一枚1115 小时前
css实现div被图片撑开
前端·css
薛一半5 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js