> 效果預覽 ![調節頁面.gif](https://wansherry.com/api/fc01e2c58219126e20367e856ebad24c.gif) > 關鍵代碼 ```javascript //調節視窗大小 useEffect(() => { if (conref.current) ...
效果預覽
關鍵代碼
//調節視窗大小
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事件里的邏輯不能進行,得不到偏移量,最終導致調節過程不流暢。