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()
},
就可以完成拖动那根线,实现两边的盒子的宽度根据线的移动而变化;
offsetLeft
和 style.left
在 Vue 或 JavaScript 中有不同的用途和含义:
1.offsetLeft:
- 是一个只读属性,表示元素相对于其最近的定位祖先元素(或视口)的左边缘的距离。
- 它返回的是一个整数,单位是像素(px)
- 用于获取元素的当前位置,不可用于设置元素的位置
2.style.left:
style.left
是一个可读写属性,表示元素在 CSS 中的left
属性值。- 它可以直接修改元素的位置。
- 用于设置元素的 CSS
left
属性,从而改变元素的位置。 - 可以设置为字符串形式,如
'100px'
或100 + 'px'
应用场景:
- 当你需要获取元素的当前位置时,使用
offsetLeft
。 - 当你需要动态改变元素的位置时,使用
style.left
。