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就可以了

相关推荐
旧梦吟24 分钟前
脚本网站 开源项目
前端·web安全·网络安全·css3·html5
北极糊的狐33 分钟前
按钮绑定事件达成跳转效果并将树结构id带入子页面形成参数完成查询功能并将返回的数据渲染到页面上2022.5.29
前端·javascript·vue.js
幽络源小助理34 分钟前
幽络源二次元分享地址发布页源码(HTML) – 源码网免费分享
前端·html
全栈前端老曹37 分钟前
【ReactNative】页面跳转与参数传递 - navigate、push 方法详解
前端·javascript·react native·react.js·页面跳转·移动端开发·页面导航
用泥种荷花1 小时前
【前端学习AI】Python环境搭建
前端
老华带你飞1 小时前
考试管理系统|基于java+ vue考试管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
_Kayo_2 小时前
React上绑定全局方法
前端·javascript·react.js
愈努力俞幸运2 小时前
chrome 扩展(插件)开发入门教程
前端·chrome
练习前端两年半2 小时前
【Vue3 高级技巧】函数重载+Watch:打造类型安全的通用事件监听 Hook
前端·javascript·vue.js
一只小鸟儿2 小时前
门户短信发送验证码及验证功能
前端·javascript·jquery