1. 程式人生 > >拖拽滾動檢視(一)

拖拽滾動檢視(一)

![](https://img2020.cnblogs.com/blog/1308525/202010/1308525-20201026144733544-359733371.png) # 滑鼠拖拽 ## 事件 ```js container.addEventListener("touchstart", dragStart, false);// 進入 container.addEventListener("touchend", dragEnd, false); // 離開 container.addEventListener("touchmove", drag, false); // 移動 container.addEventListener("mousedown", dragStart, false); // 進入 container.addEventListener("mouseup", dragEnd, false); // 離開 container.addEventListener("mousemove", drag, false);// 移動 ``` ## Element.getBoundingClientRect() 返回元素的大小及其相對視口的位置,以css設定寬高作為衡量準備 ## offset(只讀) `Element.offsetWidth` css寬度,包括`border,padding,scrollbar(水平滾動條),width` `Element.offsetHeight` css 高度,包括 `border,padding,scrollbar(垂直滾動條),height` `Element.offsetLeft` 左邊的偏移值 `Element.offsetTop` 距離頂部的偏移值 `Element.offsetParent` * 如果父級有定位,返回帶有定位的父級dom * 如果父級沒有定位,返回body ## client(只讀) 可視區域 `MouseEvent.clientWidth` 元素內部寬度(包括`padding`,不包括`scrollBar,border,margin`) `MouseEvent.clientHeight` 元素內部高度(包括`padding`,不包括`scrollBar,border,margin`) `MouseEvent.clientX` 滑鼠距離可視區域左邊的距離 `MouseEvent.clientY` ... 上邊的距離 `Element.clientTop` dom 上邊框(`border`)的寬度 `Element.clientLeft ` dom 左邊框(`border`)的寬度 ## scroll 距離: 可視區域+滾動隱藏的部分 `Element.scrollTop` 讀取設定, 距離頂部的距離 `Element.scrollLeft` 讀取設定, 距離元素left的距離 ## 拖拽效果 程式碼對映結構 ```js // 按下 box.onmousedown = function (event) { console.log(1); // 移動 box.onmousemove=function () { console.log(2); } // 抬起 box.onmouseup=function () { console.log(3); } } ``` 邏輯 * 滑鼠按下,獲取滑鼠點選時獲取相對位置 * 滑鼠移動,元素的位置=滑鼠的位置-剛剛的差值 * 滑鼠放下,給滑鼠移動和滑鼠放下設定為null ```js ``` 拖拽範圍限制 ```js /* mousedown 滑鼠進入 * mousemove 滑鼠移動 * mouseup 滑鼠離開 * */ let box = document.querySelector("#box"); let ccc = document.querySelector("#ccc"); ccc.onmousedown = function (event) { // 子盒子 let w = ccc.getBoundingClientRect().width / 2; let h = ccc.getBoundingClientRect().height / 2; // 大盒子-小盒子 let width = box.getBoundingClientRect().width - w; let height = box.getBoundingClientRect().height - h; // 按下的位置距離左側的差值 let x = event.clientX - this.offsetLeft let y = event.clientY - this.offsetTop // 移動 document.onmousemove = function (e) { // 移動的座標-左側的座標=子盒子的座標 let x1 = e.pageX - x let y1 = e.pageY - y; if (-w < x1 && x1 < width) { ccc.style.left = x1 + 'px'; } if (-h < y1 && y1 < height) { ccc.style.top = y1 + 'px'; } } // 抬起 document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; } } ``` ## 我們發現出現滾動條的一些問題 發現了會出現,滾動條的bug, 那肯定是有些東西被隱藏點了 滾動條隱藏的解決方案 ```js document.documentElement.scrollTop window.pageYOffset ``` 如果是對應的子盒子出現了滾動條,可以在對應的新增 關鍵程式碼修改 ```js // 按下的位置距離左側的差值 let x =(window.pageXOffset+ event.clientX) - this.offsetLeft let y = (window.pageYOffset+event.clientY) - this.offsetTop ``` ## 思考如何讓檢視跟著拖拽移動呢 首先理解一個比較基礎的問題 **滾動的長度** scrollTop `scrollHeight=scrollTop+clientHeight` ![](https://img2020.cnblogs.com/blog/1308525/202010/1308525-20201026132337639-1182117099.png) 同理 `scrollWidth=scrollLeft+clientWidth` 科普: 滾動的相對距離 `scrollBy(x,y)` x和y指定滾動的相對量 案例 ![](https://img2020.cnblogs.com/blog/1308525/202010/1308525-20201026142335235-55143075.gif) 整體邏輯就一句話 **移動的距離/總移動的距離=滑鼠移動的距離/總長度** 具體點就是 **滾動條移動的距離/滾動條移動的總距離=滑鼠移動的比較/總盒子可以移動的距離** 上程式碼 ```js Document