首页 > 解决方案 > 带有 flexbox 的轮播(滑块)并做出反应

问题描述

我正在尝试使用 flexbox 和 React(没有 JQuery、库或 DOM 操作)做一个 Carousel(别名 Slider)。

为了重新排序项目,我使用了orderflexbox 的属性。但是,此属性不支持任何过渡效果,因此为了实现效果,我正在尝试执行本文解释的相同操作:https ://blog.envylabs.com/the-order-property-flexbox -carousels-87a168567820(使用transform

尽管如此,我还是遇到了很多关于响应能力、不同步骤(例如将 3 张幻灯片移动到 3 张而不是仅一张)、过渡效果的问题......

如果有人可以帮助我解决这个错误的事情,我将不胜感激......经过很长时间后我现在头疼......

我在stackblitz中添加了我的代码:

另外我在这里添加代码:

轮播.js

import React, { Component } from 'react'

import './carousel.scss'

const STEP = 1

export default class Carousel extends Component {
  constructor(props) {
    super(props)
    this.next = this.next.bind(this)
    this.prev = this.prev.bind(this)
    this.resetSet = this.resetSet.bind(this)
    this.state = { ref: 0, isSet: true, isReversing: false }
  }

  getOrder(index) {
    const { items } = this.props
    const { ref } = this.state
    const order = index - ref

    if (order >= 0) {
      return order
    }

    return items.length - order
  }

  resetSet() {
    setTimeout(() => {
      this.setState({ isSet: true })
    }, 50)
  }

  next() {
    const { ref } = this.state
    const { items } = this.props
    const newRef = ref + STEP

    if (newRef < items.length) {
      this.setState({
        ref: newRef,
        isSet: false,
        isReversing: false,
      }, this.resetSet)
    }
  }

  prev() {
    const { ref } = this.state
    const newRef = ref - STEP

    if (newRef >= 0) {
      this.setState({
        ref: newRef,
        isSet: false,
        isReversing: true,
      }, this.resetSet)
    }
  }

  render() {
    const { title, items } = this.props
    const { isSet, isReversing } = this.state
    const classSet = isSet ? 'is-set' : ''
    const classReversing = isReversing ? 'is-reversing' : ''

    return (
      <>
        {title && <h2 className="carousel-title">{title}</h2>}
        <div className="carousel-wrapper" role="listbox">
          <div
            role="button"
            onClick={this.prev}
            tabIndex={0}
            className="arrow"
          >
          ⬅️
          </div>
          <div className={`carousel ${classSet} ${classReversing}`}>
            {items.map((item, index) => (
              <div
                key={item}
                style={{ order: this.getOrder(index) }}
                className="item"
              >{item}</div>
            ))}
          </div>
          <div
            className="arrow"
            role="button"
            onClick={this.next}
            tabIndex={0}
          >
          ➡️
          </div>
        </div>
      </>
    )
  }
}

轮播.scss

.carousel-title {
  font-family: 'PT_Serif-Web-BoldItalic';
  font-size: 20px;
  display: grid;
  width: 100%;
  align-items: center;
  text-align: center;
  grid-template-columns: minmax(20px, 1fr) auto minmax(20px, 1fr);
  grid-gap: 20px;

  &:before,
  &:after {
      content: '';
      border-top: 1px solid;
  }
}

.carousel-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;

  .widget {
    margin: 0 10px;
  }

  .arrow {
    cursor: pointer;
    align-self: center;
    margin: 40px;
  }

  .carousel {
    display: flex;
    flex-direction: row;
    max-width: 750px;
    overflow: hidden;
    transform: translateX(100%);

    &.is-reversing {
      transform: translateX(-100%)
    }

    &.is-set {
      transform: none;
      transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
    }

    @media(max-width: 1049px){
      width: 500px;
    }
    @media(max-width: 800px){
      width: 240px;
    }
  }
}

.item {
  background-color: #f6f6f6;
  display: flex;
  font-size: 30px;
  justify-content: center;
  align-items: center;
  min-width: 230px;
  height: 400px;
  margin: 10px
}

body {
  overflow: hidden
}

使用示例:

非常感谢你帮助我!

标签: javascripthtmlcssreactjsflexbox

解决方案


好的

所以这就是我发现的:

第一个:您以 100% 转换:所以如果显示 3 个项目,所有三个项目都会滑动,我已经设法手动处理,将 100% 更改为 250px(可能有更好的方法,但这就是想法)。

transform: translateX(250px);

&.is-reversing {
  transform: translateX(250px)
}

第二:您的 getOrder 确实返回了

items.length - order

代替

items.length + order

像这样

getOrder(index) {
    const { items } = this.props
    const { ref } = this.state
    const order = index - ref

    if (order >= 0) {
      return order;
    }
    else{
        return items.length + order;
    }

}

然后对于幻灯片,当 ref 高于 items.length 时,NEXT 没有结果

if (newRef <= items.length) {
  this.setState({
    ref: newRef,
    isSet: false,
    isReversing: false,
  }, this.resetSet)
}else{
  this.setState(
    {
      ref: 1,
      isSet: false,
      isReversing: false
    },
    this.resetSet
  );
}

你的幻灯片 PREV 应该像这样工作

if (newRef >= 0) {
  this.setState({
    ref: newRef,
    isSet: false,
    isReversing: true,
  }, this.resetSet)
}else{
  this.setState(
    {
      ref: 8,
      isSet: false,
      isReversing: true
    },
    this.resetSet
  );
}

如您所见,我添加了一些诸如 250px 和“8”之类的东西,它们可能会被添加,例如 250px 是项目宽度,而 8 是数组的最后一个索引。

我也意识到你的过渡总是向左滑动。我一有时间就可以看得更远,但现在我设法做到了,

我希望它有帮助,不确定我是否解释得很好,但我尽力了。

玩得开心

https://stackblitz.com/edit/carousel-pov-rvftku

编辑:在 stackblitz 上添加了一个轮播叉


推荐阅读