React实现可页面可调节
效果预览
关键代码
//调节窗口大小
useEffect(() => {
if (conref.current) {
conref.current.style.width = `${conref.current.clientWidth + delta}px`
let t = conref.current.clientWidth + conref.current.offsetLeft + 2
start.current = t
}
}, [delta])
//dom结构
<div
onMouseMoveCapture={(e) => { if (moving) { setdelta(e.clientX - start.current) } }}
onMouseUp={(e) => { moving && setmoving(false) }}
className="commentManager_body">
<div ref={conref} className="commentManager_articlelist">
{
articles && articles.map(item => <NavLink to={`/articleManage/manageComments/${item.id}`} key={item.id}>{item.title}</NavLink>)
}
</div>
<div
//移动端事件
onTouchStart={(e) => { start.current = e.touches[0].clientX }}
onTouchMove={(e) => { setdelta(() => e.touches[0].clientX - start.current) }}
onMouseDown={(e) => { setmoving(true); start.current = e.clientX + 5 }}
onMouseUp={(e) => { moving && setmoving(false) }}
className="adjustBar"></div>
<div className="commentManager_commentlist">
<Outlet></Outlet>
</div>
</div>
原理
整个窗口分为三个区域,左侧为文章列表,右侧是用来展示对应文章评论的区域,中间设置了一个宽度为10的区域,用来调节两边区域的大小。
首先,将最大的容器设置为display:flex;
左边的容器设置一个初始宽度,
中间的元素设置固定宽度为10px
右侧容器设置flex:1;填充外层容器剩余空间
处理移动端
在中间的控制条上添加两个事件,一个是onTouchStart,用于记录在一开始触摸时的位置,另一个是onTouchMove,获取手指在屏幕上移动的位置,并减去开始的位置,获取x方向的偏移量。根据这个偏移量来调节左侧容器的宽度,并更新初始值,就实现了预期的效果。
处理PC端
与移动端不同,在PC端需要使用三个事件函数,onMouseDown,标记此时开始调节大小,设置最开始的位置,onMouseMove,获取鼠标移动到的位置,减去初始值获得x方向偏移量,根据偏移量调节左侧容器的宽度,onMouseUp,标记此时不需要调节大小。
注意的是PC端鼠标始终在屏幕上,所以需要一个变量来区分何时鼠标移动需要调节大小,何时不需要,同时将onMouseMove事件绑定在最外层盒子上,可以避免由于中间的控制条太窄,鼠标在移动时偏到外面,造成的move事件里的逻辑不能进行,得不到偏移量,最终导致调节过程不流畅。