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

[复制链接]
发表于 2026-1-18 03:54:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
DOM结构:
  1. <div class="courer">  // 外层盒子
  2.       <div  class="dividing-line" title="拖动"></div>  // 拖动的那个线
  3.       <div class="course-title-box">  // 第一个盒子
  4.         <div class="course-content-box" v-infinite-scroll="load" infinite-scroll-disabled="disabled">
  5.          
  6.           <div v-for="(item2, i2) in detialList" :key="i2" @contextmenu="handleRightClick(i2, item2)">
  7.             <!--标题-->
  8.             <div class="course-content-item" @click="currentChange(item2)">
  9.               <div style="width: calc(100% - 50px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
  10.               
  11.                 {{ item2.name }}
  12.               </div>
  13.             </div>
  14.           </div>
  15.          
  16.           <div v-if="noMore" style="color: #999; font-size: 12px; text-align: center; margin: 10px 0">没有更多了</div>
  17.         </div>
  18.       </div>
  19.       <div class="course-detail-content-box" style="display: flex; align-items: center; justify-content: center">// 第二个盒子
  20.         <div style="color: #bdbdbd">
  21.           <span>点击任务标题查看详情</span>
  22.         </div>
  23.       </div>
  24.       
  25.     </div>
复制代码
css样式:
  1. .courer {
  2.   /* padding: 20px; */
  3.   width: calc(100% - 150px);
  4.   height: 100%;
  5.   overflow-y: auto;
  6.   overflow-x: hidden;
  7.   display: flex;
  8.   position: relative;
  9. }
  10. .dividing-line {
  11.   position: absolute;
  12.   width: 10px;
  13.   height: 100%;
  14.   left: 200px;
  15.   top: 0;
  16.   transform: translate(-50%, 0);
  17.   cursor: col-resize;
  18.   /* background-color: rgba(20, 20, 23, 0.3); */
  19.   background-color: transparent;
  20. }
  21. .course-title-box {
  22.   width: 200px;
  23.   height: 100%;
  24.   overflow-y: auto;
  25.   overflow-x: hidden;
  26.   /* background-color: #789; */
  27.   border-right: 1px solid rgba(0, 0, 0, 0.07);
  28.   border-top: 1px solid rgba(0, 0, 0, 0.07);
  29.   padding: 5px 15px;
  30.   .course-title-item {
  31.     cursor: pointer;
  32.     padding: 10px 0;
  33.     color: #333;
  34.     font-weight: 700;
  35.     /* background-color: #669; */
  36.     position: relative;
  37.     &:hover {
  38.       color: #5fa4f6;
  39.       .el-icon-more-outline {
  40.         display: block;
  41.       }
  42.     }
  43.     .el-icon-more-outline {
  44.       display: none;
  45.     }
  46.     span {
  47.       padding: 0 7px;
  48.     }
  49.     .add {
  50.       position: absolute;
  51.       right: 5px;
  52.       top: 13px;
  53.     }
  54.   }
  55.   .course-content-box {
  56.     .course-content-item {
  57.       color: #333;
  58.       cursor: pointer;
  59.       padding: 10px;
  60.       /* background-color: #898; */
  61.       border-bottom: 1px solid rgba(0, 0, 0, 0.03);
  62.       position: relative;
  63.       &:hover {
  64.         background-color: #e7f3ff;
  65.       }
  66.       .detail-box {
  67.         position: absolute;
  68.         right: 13px;
  69.         top: 0;
  70.         height: 40px;
  71.         display: flex;
  72.         align-items: center;
  73.         .more-icon:hover {
  74.           color: #5fa4f6;
  75.         }
  76.       }
  77.     }
  78.     .active-course-content-item {
  79.       background-color: #e7f3ff;
  80.     }
  81.   }
  82. }
复制代码
重中之重的js代码:
  1. // methods里的
  2.     setTaskBox() {
  3.       if (window.localStorage.getItem('lineLeft') != null) {
  4.         const titleBox = document.getElementsByClassName('course-title-box')[0]
  5.         const contentBox = document.getElementsByClassName('course-detail-content-box')[0]
  6.         const line = document.getElementsByClassName('dividing-line')[0]
  7.         line.style.left = window.localStorage.getItem('lineLeft') + '%'
  8.         titleBox.style.width = window.localStorage.getItem('titleBoxWidth') + '%'
  9.         contentBox.style.width = window.localStorage.getItem('contentBoxWidth') + '%'
  10.       }
  11.     },
  12.     // 实现任务列表和任务详情显现区域变化功能
  13.     changeTaskBox() {
  14.       const titleBox = document.getElementsByClassName('course-title-box')[0]
  15.       const contentBox = document.getElementsByClassName('course-detail-content-box')[0]
  16.       const line = document.getElementsByClassName('dividing-line')[0]
  17.       const box = document.getElementsByClassName('courer')[0]
  18.       let titleBoxStyle = window.getComputedStyle(titleBox)
  19.       let contentBoxStyle = window.getComputedStyle(contentBox)
  20.       let boxStyle = window.getComputedStyle(box)
  21.       console.log(titleBoxStyle.width, contentBoxStyle.width, boxStyle.width)
  22.       // 鼠标按下事件
  23.       line.onmousedown = e => {
  24.         let titleBoxWidth = parseFloat(titleBoxStyle.width)
  25.         let contentBoxWidth = parseFloat(contentBoxStyle.width)
  26.         let boxWidth = parseFloat(boxStyle.width)
  27.         const startX = e.clientX
  28.         console.log('startX', startX)
  29.         const lineLeft = line.offsetLeft
  30.         console.log('lineLeft', lineLeft)
  31.         // 鼠标拖动事件
  32.         document.onmousemove = e => {
  33.           const moveX = e.clientX
  34.           console.log('moveX', moveX)
  35.           // 鼠标移动距离
  36.           let moveLen = lineLeft + moveX - startX
  37.           moveLen = moveLen < 200 ? 200 : moveLen //左边区域最小宽度为200px
  38.           moveLen = moveLen > boxWidth - 500 ? boxWidth - 500 : moveLen //右边区域最小宽度为500px
  39.           line.style.left = moveLen + 'px'
  40.           titleBox.style.width = moveLen + 'px'
  41.           contentBox.style.width = boxWidth - moveLen + 'px'
  42.           titleBoxWidth = parseFloat(titleBoxStyle.width)
  43.           contentBoxWidth = parseFloat(contentBoxStyle.width)
  44.         }
  45.         // 鼠标松开事件
  46.         document.onmouseup = function () {
  47.           let newLineLeft = (parseInt(line.offsetLeft) / boxWidth).toFixed(2) * 100
  48.           let newTitleBoxWidth = (titleBoxWidth / boxWidth).toFixed(2) * 100
  49.           let newContentBoxWidth = (contentBoxWidth / boxWidth).toFixed(2) * 100
  50.           window.localStorage.setItem('titleBoxWidth', newTitleBoxWidth)
  51.           window.localStorage.setItem('contentBoxWidth', newContentBoxWidth)
  52.           window.localStorage.setItem('lineLeft', newLineLeft)
  53.           document.onmousemove = null
  54.           document.onmouseup = null
  55.         }
  56.         return false
  57.       }
  58.     },
复制代码
e.clientX 是一个事故对象的属性,它表现鼠标指针相对于欣赏器视口(viewport)的水平位置。详细来说,e.clientX 返回鼠标指针相对于视口左边沿的 x 坐标。
mounted里的:
  1.   mounted() {
  2.     this.changeTaskBox()
  3.     this.setTaskBox()
  4.   },
复制代码
就可以完成拖动那根线,实现两边的盒子的宽度根据线的移动而变革;
offsetLeft 和 style.left 在 Vue 或 JavaScript 中有差别的用途和寄义:
1.offsetLeft:

  • 是一个只读属性,表现元素相对于其迩来的定位先人元素(或视口)的左边沿的隔断。
  • 它返回的是一个整数,单位是像素(px)
  • 用于获取元素的当前位置,不可用于设置元素的位置
 2.style.left:

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

  • 当你必要获取元素的当前位置时,使用 offsetLeft。
  • 当你必要动态改变元素的位置时,使用 style.left。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表