我使用了 onMouseDown onMouseMove 和 onMouseUp 来实现了拖拽划动。
代码
import React, { MutableRefObject, useRef } from 'react'
import { throttle } from 'lodash'
import styles from './index.less'
export default () => {
const ScrollContainer: MutableRefObject<HTMLDivElement | null> = useRef(null)
let downScrollLeft = 0
let downClientX = 0
let downScrollTop = 0
let downClientY = 0
let isMoving = false
const handleMouseDown = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
) => {
isMoving = true
if (ScrollContainer.current) {
downClientX = event.clientX
downScrollLeft = ScrollContainer.current.scrollLeft
downClientY = event.clientY
downScrollTop = ScrollContainer.current.scrollTop
}
}
const scrollCallback = throttle((clientX: number, clientY: number) => {
if (isMoving && ScrollContainer.current) {
ScrollContainer.current.scrollLeft =
downScrollLeft + (downClientX - clientX)
ScrollContainer.current.scrollTop =
downScrollTop + (downClientY - clientY)
}
}, 16)
const handleMouseMove = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
) => scrollCallback(event.clientX, event.clientY)
const handleMouseUp = () => {
isMoving = false
}
return (
<div
className={styles.container}
ref={ScrollContainer}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
>
<div className={styles.content}>content</div>
</div>
)
}
.container {
width: 600px;
height: 600px;
overflow: auto;
}
.content {
width: 1200px;
height: 1200px;
background: rgb(144, 203, 243);
}
原理
- 修改容器元素的 scrollTop 和 scrollLeft 来进行容器内容的纵向和横向滑动。
- 通过鼠标事件记录鼠标位置,并计算鼠标位移距离。
- 通过 lodash 的节流函数避免 onMouseMove 过快调用。
最后
这些 API 的具体资料可以去查阅 MDN,其实实现起来并不难,主要是知道这些 API 的存在并结合起来使用。








网友评论