【问题标题】:Material UI Carousel - with autoscrollMaterial UI Carousel - 带自动滚动
【发布时间】:2020-12-02 09:56:52
【问题描述】:

我正在反应中构建一个轮播组件——客户希望有一个自动滚动选项——我担心的是干扰用户界面——构建什么样的逻辑来中断/暂停自动滚动而不干扰用户首先尝试使用它。那么需要悬停检测吗?

//原始轮播 https://codesandbox.io/s/holy-https-h0yv3

//开启当前自动滚动选项 - 但忽略所有用户界面注意事项 https://codesandbox.io/s/nervous-brown-2inki?file=/src/Carousel/Carousel.js

另外 - 滑过幻灯片后的旋转木马 - 只会在甲板上拉开 - 无法捕捉到幻灯片 - 所以这是另一个问题

import React, { Component } from 'react';

import Button from '@material-ui/core/Button';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';

import './Carousel.scss';

class Carousel extends Component {
    constructor() {
      super();
      this.myRef = React.createRef();
      this.state = {
        currentSlide: 0,
        slideWidth: 0,
        slideCount: 0
      };
      this.updateDimensions = this.updateDimensions.bind(this);
      this.handleKeyPress = this.handleKeyPress.bind(this);

      this.prev = this.prev.bind(this);
      this.next = this.next.bind(this);
    }

    componentDidMount() {
      window.addEventListener("resize", this.updateDimensions);
      this.updateDimensions();

      this.setState({
        slideCount: this.props.items.length
      });

      this.autoSlide();
    }

    componentWillUnmount() {
      window.removeEventListener("resize", this.updateDimensions);
    }

    handleKeyPress(e) {
      if (e.keyCode === 39) {
        this.next();
      }
      if (e.keyCode === 37) {
        this.prev();
      }
    }

    updateDimensions(){
      //update the dimensions of the slide for responsiveness
      this.setState({
        slideWidth: this.myRef.current.getBoundingClientRect().width
      });
    }

    prev(){
      //if the current slide won't hit negative slide - change current slide
      if(this.state.currentSlide > 0){
        let prevSlide = this.state.currentSlide-1;
        this.setState({
          currentSlide: prevSlide
        });
      }
    }

    next(){
      //if the next slide will not go beyond the items - change current slide
      if(this.state.currentSlide < this.props.items.length-1){
        let nextSlide = this.state.currentSlide+1;
        this.setState({
          currentSlide: nextSlide
        });
      }
    }

    selected(slide){
      console.log(slide)
      this.setState({
        currentSlide: slide
      });
    }

    autoSlide(){
      let that = this;
      let count = this.props.items.length;

      let i = 0;
      setInterval(function(){ 
        that.selected(i);
        i++;

        if(count === i){
          i=0;//resets
        }
      }, 3000);
    }

    render() {
        return (
          <div ref={this.myRef} className="carousel" onKeyDown={this.handleKeyPress} tabIndex={-1}>
            <div className="carousel-holder">
              <div className="carousel-wrapper">
                  <div 
                    className="slide-wrapper"
                    style={{
                      left: -this.state.slideWidth*this.state.currentSlide,
                      width: this.state.slideWidth*this.state.slideCount
                    }}
                  >
                  {
                    this.props.items.map((item, j) => {
                      return(
                        <div 
                          key={j}
                          className="slide" 
                          style={{
                            width: this.state.slideWidth
                          }}               
                        >
                          <div className={"gutter " + (this.props.hasGutter? "has-gutter" : "")}>
                            {item.slide}
                          </div>
                        </div>
                      )
                    })
                  }
                  </div>
              </div>

              <Button 
                className="carousel-arrow prev-arrow"
                onClick={this.prev}
                disabled={(this.state.currentSlide === 0)}
              >
                <ChevronLeftIcon />
              </Button>

              <Button 
                className="carousel-arrow next-arrow"
                onClick={this.next}
                disabled={(this.state.currentSlide === this.props.items.length-1)}
              >
                <ChevronRightIcon />
              </Button>
            </div>

            <div className="carousel-dots">
              <ul className="dot-wrapper">
                {
                  this.props.items.map((item, x) => {
                    return (
                      <li 
                        key={x}
                        className={(this.state.currentSlide === x? "selected" : "")}
                      >
                        <Button 
                          className="dot"
                          onClick={() => this.selected(x)}
                        />
                      </li>
                    )
                  })
                }
              </ul>
            </div>
          </div>
        );
    }
}

export default Carousel;

【问题讨论】:

    标签: reactjs material-ui carousel


    【解决方案1】:

    您应该创建一个布尔值 shouldAutoScroll,它应该作为 prop 传递给这个 Carousel 组件。最初,它的值为 true,这意味着此幻灯片应自动滚动,基于您可以不断更改活动幻灯片的时间间隔。

    用户将鼠标悬停在图像上,或者一旦用户单击下一个/上一个按钮,将 shouldAutoScroll 设置为 false,这意味着应该停止自动滚动逻辑。

    this.state = {
          shouldAutoScroll: true,
        ...
        }
    

    因为您已经在 componentDidMount 上调用它

    componentDidMount() {
        ...
        this.state.shouldAutoScroll && this.autoSlide();
      }
    

    next()prev() 上切换它的值,确定用户想要控制滚动。

    next/prev () {
    this.setState(p => p.shouldAutoScroll && ({...p, shouldAutoScroll: false}));
    ... // further logic
    }
    

    【讨论】:

    • 您能否将您的解决方案调整到沙箱进行测试?
    • 是的,你可以在这里查看:codesandbox.io/s/divine-sun-e4ftx
    • 虽然不起作用——我猜 autoScroll=true 应该是您调用轮播的主页上的一个属性。 -- 在最后一张幻灯片上,如果我将鼠标悬停在幻灯片上,它不会停止自动滚动,如果我点击箭头,它会在再次开始自动滚动时忽略我的选择
    【解决方案2】:

    我不确定如何根据您的期望在给定场景中调整您的代码。但我也希望在我的轮播中做同样的事情。然后我发现了这个npm package,可以用来展示轮播。我认为您也可以使用它来纠正您的问题。

    【讨论】:

    • 是的 - 当时还没有提出请求。我制作了自己的轮播 - 所以我可以控制对它的响应性方面
    • 我不想无故添加新模块 --
    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 2017-04-12
    • 2021-04-05
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多