拖拽滾動檢視(一)
阿新 • • 發佈:2020-10-26
![](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