【问题标题】:Carousel (slider) with flexbox and react带有 flexbox 的轮播(滑块)并做出反应
【发布时间】:2019-02-05 11:04:03
【问题描述】:

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

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

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

如果有人能帮助我解决这个错误的问题,我将不胜感激......经过很多时间后,我现在头疼......

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

另外我在这里添加代码:

carousel.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>
      </>
    )
  }
}

carousel.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
}

使用示例:

  • &lt;Carousel title="My carousel" items={[1,2,3,4,5,6,7,8,9]} /&gt;

非常感谢您对我的帮助!

【问题讨论】:

  • 到目前为止做得很好,我正在检查这个是否可以提供帮助;)
  • @DanielVafidis 我很感激。非常感谢

标签: javascript html css reactjs flexbox


【解决方案1】:

好的

这就是我发现的:

第一个:您转换为 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 上添加了一个轮播分叉

【讨论】:

    猜你喜欢
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多