在浏览器中封装横向滚动组件确实不是很必要,但是产品说过用户不一定知道shfit+鼠标滚轮就是横向滚动
而普通的监听没有原生的滚动丝滑,借鉴曾经看过的抖音上渡一老师的思路封装了一个横向滚动的组件
ts
import React from 'react';
import { ConstructorParamsBase, PageInstance } from '@/abstractClass/PageInstance';
interface State {
width: number,
height: number,
}
export class XScrollInstance extends PageInstance<State> {
vScrollRef = React.createRef<HTMLDivElement>();
constructor({ forceUpdate, state }: ConstructorParamsBase<State>) {
super();
this.setForceUpdate(forceUpdate);
this.setState({
height: 0,
width: 0,
...state,
});
}
scrollLeft(scrollNumber: number) {
this.vScrollRef.current.scrollTop -= scrollNumber;
this.forceUpdate();
}
scrollRight(scrollNumber: number) {
this.vScrollRef.current.scrollTop += scrollNumber;
this.forceUpdate();
}
}
ts
import React, { FC, MutableRefObject, useRef } from 'react';
import {
useCreation, useSize, useUnmount, useUpdate,
} from 'ahooks';
import { css, cx } from '@emotion/css';
import styles from './XScroll.css';
import { XScrollInstance } from './XScrollInstance';
interface Props {
children: React.ReactNode;
instanceRef?: MutableRefObject<XScrollInstance>,
containerClassName?: string
}
export const XScroll: FC<Props> = ({ children, instanceRef, containerClassName }) => {
const forceUpdate = useUpdate();
const xScrollRef = useRef();
const size = useSize(xScrollRef);
const pageInstance = useCreation(() => {
const instance = new XScrollInstance({ forceUpdate, state: {} });
if (instanceRef) {
instanceRef.current = instance;
}
return instance;
}, []);
pageInstance.setState({
width: size?.width || 0,
height: size?.height || 0,
});
useUnmount(() => {
if (instanceRef) {
instanceRef.current = null;
}
});
return (
<div
ref={xScrollRef}
className={cx(css`width: 100%;height: 100%;`, containerClassName)}
>
<div
ref={pageInstance.vScrollRef}
className={cx(styles.vScroll, css`
position: relative;
width: calc(${size?.height} * 1px);
height: calc(${size?.width} * 1px);
overflow: auto;
scroll-behavior: smooth;
transform-origin: 0 0;
transform: translateY(calc(${size?.height} * 1px)) rotate(-90deg);
`)}
>
<div
className={cx(css`
height: calc(${size?.height} * 1px);
position: absolute;
left: 100%;
transform-origin: 0 0;
transform: rotate(90deg);
padding-top: 1px;
`)}
>
{children}
</div>
</div>
</div>
);
};
css
.vScroll::-webkit-scrollbar {
width: 0;
}
用法只需用组件包裹过长dom就可以了