Accordion做出了与奇怪的行为切换标签的反应

时间:2017-05-25 21:23:21

标签: javascript reactjs dom accordion

我做了手风琴的反应,除了一个之外几乎完成了。单击另一个应该关闭上一个选项卡的选项卡后的行为(仅允许一个选项卡)并将顶部滚动到视口的0。

问题是,当我第一次点击选项卡时,它们的行为正确,但是当我点击任何一个标签后,他们打开并滚动顶部,但是在他们"向上移动" dom可能是最后一个标签的偏移差异。我尝试了很多东西,我得到的最好的是带有一些settimeout的scrollToTop,但是它们滚动了前一个标签的整个偏移量,而不是仅仅将视口的其余部分移动到顶部。

总结:
1-第一个标签滚动正确顶部
2-第二个标签正确关闭第一个标签,滚动顶部但是它们会移动"而不是扩展。

总结:
1-第一个标签滚动正确顶部
2-第二个标签正确关闭第一个标签,滚动顶部但是它们会移动"而不是扩展。

纠正行为: https://media.giphy.com/media/l0Iy9aw7hhVkiZRvO/giphy.gif

行为错误: https://media.giphy.com/media/3o7bu1ZEGPexohh6Sc/giphy.gif

我创建了一个PLUNKER试图完成MCVE,但没有成功,但这是我的代码。

两个主要脚本是 Materias.js MateriaExpanded.js

我已经检查过我的错误是当我生成哪个元素打开时(就像我说只允许一个元素)。 在 Materias.js

  ownToggle(id, ref, e) {
    const self = this.state.elementsOpen[id];
    const hash = this.generateElementsOpen(this.props.items, id);
    if (!self) {
      hash[id] = true;
    }
    this.setState({
      elementsOpen: hash, // bug
    });

  }

我在 MateriaExpanded.js

中的摘录
import React, { Component, PropTypes } from 'react';
import FontAwesome from 'react-fontawesome';
import $ from 'jquery';
import moment from 'moment';
import Content from './Content.js';
import Footer from './Footer.js';
import './style.css';

class MateriaExpanded extends Component {
  constructor(props) {
    super(props);
    this.renderSocialNetworks = this.renderSocialNetworks.bind(this);
    this.childToggle = this.childToggle.bind(this);
    this.renderTimeDiff = this.renderTimeDiff.bind(this);
    this.className = this.className.bind(this);
    this.disableThumbor = this.disableThumbor.bind(this);
  }
  componentDidMount() {
    this.props.materiasContainers(this.containerRef);
  }
  childToggle(itemId, ref, e) {
    this.props.calcViewPort(itemId, ref, false);
    setTimeout(() => { this.props.ownToggle(itemId, ref, e) }, 400);
  }
  className() {
    if (this.props.isOpen && this.props.item.img_url.length < 1) {
      return 'withoutImg containerImageFluid';
    }
    if (this.props.isOpen && this.props.item.img_url.length > 0) {
      return 'containerImageFluid';
    }
    if (!this.props.isOpen && this.props.item.img_url.length < 1) {
      return 'containerImageSimple withoutImg';
    }
    if (!this.props.isOpen && this.props.item.img_url.length > 0) {
      return 'containerImageSimple';
    }
    return;
  }
  disableThumbor() {
    const newUrl = this.props.item.img_url.split('http://');

    const newUrlWithoutThumbor = newUrl[newUrl.length - 1];

    return `url(http://${newUrlWithoutThumborcontent})no-repeat top center`;
  }

  render() {
    return (
      <div
        className={this.props.isOpen ? 'opened' : 'closed'}
        ref={(containerRef) => { this.containerRef = containerRef; }}
      >
        <div 
          onClick={(e) => this.childToggle(this.props.item.id, this.containerRef, e)}
          className={this.className()}
          style={{
            background: this.disableThumbor(),
            transitionTimingFunction: 'cubic-bezier(0.9, 0.54, 0.33, 0.85)',
            transitionDuration: '1.1s',
            transform: 'translate3d(0px, 0px, 0px)',
            backgroundSize: 'cover',
          }}
        >
          { this.props.item.is_video ?
            (
              <FontAwesome
                className={style.videoStyle}
                name="play"
              />
            ) : null
          }
        </div>
        <div className={style.containerContent}>
          <div>
            <div onClick={(e) => this.childToggle(this.props.item.id, this.containerRef, e)}>
              <div className={style.resume}>
                <span className={this.props.isOpen ? 'descriptionOpened' : 'description'}>{this.props.item.category}</span>
                <span className={style.descriptionTime}>TIME</span>
              </div>
              <h1 className={this.props.isOpen ? 'materiaOpen' : 'title'}>{this.props.item.title} </h1>
              <h3 className='preview'>{this.props.item.subtitle}</h3>
              <div className={style.socialNetwork}> social networks </div>
            </div>
          </div>
          <div className={this.props.isOpen ? 'containerMateria' : 'containerHide'}>
            <HeaderComponent
              title={this.props.item.title}
              id={this.props.item.id}
              subtitle={this.props.item.subtitle}
              category={this.props.item.categoria}
            />
            <Content content={this.props.item.content.body} time={this.renderTimeDiff()} />
            <Footer />
          </div>
        </div>
      </div>
    );
  }
}

export default MateriaExpanded;

MateriaExpanded.propTypes = {
  item: PropTypes.object.isRequired,
  items: PropTypes.func,
  changeHeaderExpanded: PropTypes.func,
  toggle: PropTypes.func,
  materiasContainers: PropTypes.func,
  materiaClick: PropTypes.func,
  isOpen: PropTypes.bool,
  ownToggle: PropTypes.func,
  calcViewPort: PropTypes.func,
};

编辑1 :我在github上创建了一个临时仓库来帮助人们检查我的bug https://github.com/yuripramos/temp-multicontent

0 个答案:

没有答案