react封装横向滚动组件

在浏览器中封装横向滚动组件确实不是很必要,但是产品说过用户不一定知道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就可以了

相关推荐
gnip13 分钟前
组件循环引用依赖问题处理
前端·javascript
Aotman_1 小时前
el-input textarea 禁止输入中文字符,@input特殊字符实时替换,光标位置保持不变
前端·javascript·vue.js·前端框架·es6
Nan_Shu_6141 小时前
Web前端面试题(1)
前端·面试·职场和发展
lypzcgf1 小时前
Coze源码分析-资源库-创建知识库-前端源码-核心组件
前端·typescript·react·coze·coze源码分析·ai应用平台·agent开发平台
百思可瑞教育2 小时前
在Vue项目中Axios发起请求时的小知识
前端·javascript·vue.js·北京百思教育
患得患失9492 小时前
【个人项目】【前端实用工具】OpenAPI to TypeScript 转换器
前端·javascript·typescript
大前端helloworld2 小时前
前端梳理体系从常问问题去完善-基础篇(html,css,js,ts)
前端·javascript·面试
trsoliu3 小时前
前端基于 TypeScript 使用 Mastra 来开发一个 AI 应用 / AI 代理(Agent)
前端·人工智能
鸡吃丸子3 小时前
前端权限控制:深入理解与实现RBAC模型
前端
Larry_zhang双栖3 小时前
低版本Chrome 内核兼容性问题的优美解决
前端·chrome