1

我们如何/可以在 CSS 中使可见幻灯片的数量响应?/ 不必使用 JS 来visibleSlides根据断点进行更改。

例如; 每张幻灯片都有 min-width: 100px; min-height: 100px;ie。我们希望看到细节的图像不应该小于 100px。

我们设置visibleSlides为 8(用于桌面)。在移动设备上,我们只想显示 2 张幻灯片。因为我们不希望单个幻灯片的高度和宽度小于 100 像素,也不希望幻灯片重叠。

我知道我们可以使用 react 来检查屏幕宽度和设置visibleSlides,但是所有应用程序都可以访问它并不容易,尤其是像 next.js 那样呈现的服务器端。

请参阅此沙箱https://codesandbox.io/s/pure-react-carousel-responsive-visible-slides-k8cui

(来自https://codesandbox.io/s/withered-wood-4bx36?fontsize=14&hidenavigation=1&theme=dark

4

2 回答 2

1

我的应用程序遇到了这个问题,实际上找不到使用CSS. 但是,我已经使用ResizeObserverand实现了这个react-hooks
PS我正在使用next js,在服务器端实现它并不是什么大问题。
这是我的解决方案,希望对您有所帮助。
步骤 1. 创建一个观察者钩子来监听来自应用程序的调整大小事件。

import { useEffect, useState, RefObject } from 'react';
import ResizeObserver from 'resize-observer-polyfill';

interface DOMRectReadOnly {
  readonly bottom: number;
  readonly height: number;
  readonly left: number;
  readonly right: number;
  readonly top: number;
  readonly width: number;
  readonly x: number;
  readonly y: number;
}

interface useResizeObserverProperties {
  ref?: RefObject<Element> | null;

  element?: Element | null | undefined;

  callback?: (entry: ResizeObserverEntry) => void;
}

const IS_BROWSER = typeof window !== 'undefined';

/**
 * Watch for the resizing of a React component or Element.
 *
 * @param hookProperties - Configuration optinos for the hook.
 *
 * @returns The `DOMRect` for the observed element.
 */
export const useResizeObserver = ({
  ref,
  element,
  callback,
}: useResizeObserverProperties) => {
  const [sizes, setSizes] = useState<DOMRectReadOnly>({
    bottom: 0,
    height: 0,
    left: 0,
    right: 0,
    top: 0,
    width: 0,
    x: 0,
    y: 0,
  });

  const handleResize = (entries: ResizeObserverEntry[]) => {
    const [entry] = entries;

    if (callback) callback(entry);

    setSizes(entry.contentRect);
  };

  const [resizeObs] = useState(() =>
    IS_BROWSER ? new ResizeObserver(handleResize) : undefined,
  );

  useEffect(() => {
    if (!resizeObs) return;
    let domNode;

    if (ref) {
      domNode = ref.current;
    } else if (element) {
      domNode = element;
    }

    if (domNode) {
      resizeObs.observe(domNode);
    }

    return () => resizeObs.disconnect();
  }, [ref, resizeObs, element]);

  return sizes;
};

第 2 步。在您的component.tsx


import React, { useState, useRef } from 'react';
import { CarouselProvider, Slider, Slide } from 'pure-react-carousel';
import { useResizeObserver } from 'from previously created file';

const YourComponent = () => {
  const [visibleSlides, setVisibleSlides] = useState(1);
  const ref = useRef<HTMLDivElement>(null);

  // Current width of element
  const { width } = useResizeObserver({ ref });

  switch (true) {
    case width > 768 && width < 1280:
      setVisibleSlides(2);
      break;
    /**
     * Switch your cases here
     */
  }

  return (
    <div ref={ref}>
      <CarouselProvider
        naturalSlideWidth={100}
        naturalSlideHeight={125}
        totalSlides={3}
        visibleSlides={visibleSlides}
      >
        <Slider>
          <Slide index={0}>Slide 1</Slide>
          <Slide index={1}>Slide 2</Slide>
          <Slide index={2}>Slide 3</Slide>
        </Slider>
      </CarouselProvider>
    </div>
  );
};

export default YourComponent;

顺便说一句,我建议您throttle setVisibleSlides在从开发工具调整窗口大小时调用以避免过多的重新渲染。

于 2020-04-07T21:56:04.643 回答
0

不是答案,但我正在尝试做同样的事情。如何useStatevisibleSlides整数使用 React 钩子,并创建一个窗口侦听器来侦听断点并根据需要更改状态......

于 2020-03-28T02:50:11.460 回答