CSS 能实现鼠标滚轮的横向滚动-React版

283 阅读1分钟

使用React 封装的鼠标滚轮横向滚动组件,支持滚动到可视化位置。

组件实现XScrollBox

import * as React from 'react';

import styles from './index.less';

const { useRef, useEffect, useState, useImperativeHandle } = React;

const Index = ({ children, instanceRef }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const obRef = useRef<ResizeObserver>();
  const [containerRect, setContainerRect] = useState<Record<string, any>>({});
  const getResizeObserver = () => {
    obRef.current = new ResizeObserver(entries => {
      for (const entry of entries) {
        const box = entry.borderBoxSize[0];
        setContainerRect({ width: box.inlineSize, height: box.blockSize });
      }
    });
    obRef.current.observe(containerRef.current!);
  };

  useImperativeHandle(instanceRef, () => ({
    scrollTo: options => {
      scrollRef.current?.scrollTo(options);
    },
  }));

  useEffect(() => {
    getResizeObserver();

    return () => {
      containerRef.current && obRef.current?.unobserve(containerRef.current);
    };
  }, []);

  return (
    <div ref={containerRef} className={styles['container']}>
      <div
        ref={scrollRef}
        className={styles['scroll']}
        style={{
          width: `${containerRect.height}px`,
          height: `${containerRect.width}px`,
          transform: `translateY(${containerRect.height}px) rotate(-90deg)`,
        }}
      >
        <div
          className={styles['content']}
          style={{
            height: `${containerRect.height}px`,
          }}
        >
          {children}
        </div>
      </div>
    </div>
  );
};

export default React.forwardRef<any, any>((props, ref) => (
  <Index {...props} instanceRef={ref} />
));


样式部分

.container {
  width: 100%;
  height: 100%;
}

.scroll {
  position: relative;
  overflow: auto;
  transform-origin: 0 0;
  scroll-behavior: smooth;
}

.content {
  position: absolute;
  left: 100%;
  transform-origin: 0 0;
  transform: rotate(90deg);
}

组件使用

<div className={styles.left}>
 <XScrollBox>
      <div className={styles['left-box']}>
        {list.map(item => {
          return (
            <div key={item.value}>
              <div className={styles['mark']}></div>
              <div className={styles['value']}>{item.label}</div>
            </div>
          );
        })}
      </div>
    </XScrollBox>
</div>

样式部分

.left{
    width:100%;
    height:50px;
}

.left-box{
      padding: 24px 0;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      justify-content: flex-start;
}

去掉顶部滚动条

 ::-webkit-scrollbar {
    width: 0;
    height: 0;
  }

参考