使用transitionend事件侦听器进行响应以创建转换

时间:2017-09-05 21:06:48

标签: javascript reactjs transition transitionend

我尝试进行简单的转换,在按钮单击时做出反应,其中body max-height在componentWill更新时变为0,然后在componentDidUpdate上返回500px或100%。我还没有从我见过的其他问题中明白这一点,所以有人可以给我一个例子来解释它是如何工作的吗?

我也不会介意使用reactcsstransitiongroup进行示例/解释。

更多信息

我理解,transitionend附加了一个事件监听器,但我对此感到困惑的是如何使用它来确保组件在转换完成之前不会更新(我自学了自己的反应)几乎所有的编码知识都让我不知道这是不是很难理解,但现在对我来说很难。谢谢大家!

1 个答案:

答案 0 :(得分:4)

所以经过一段时间的休息,我决定是时候再来一章“学生教学生”(由我指导并主演)。

为了更自觉地解决我自己的问题,transitionend事件监听器将一个监听器附加到一个元素,并在转换结束时触发一个回调函数。我遇到的问题是这是异步的,因此,将它放入componentWillUpdate将无法工作,因为DOM将在转换完成之前呈现。我目前的解决方法是让按钮单击调用包含事件侦听器的函数,并使用trnasitionend的回调函数更改组件的状态。这样,在转换完成之前不会进行渲染。

代码:

class Button2 extends React.Component {
  constructor(props){
    super(props)
    this.onClickHandler = this.onClickHandler.bind(this)
  }

  onClickHandler(){
    this.props.onClick("Button2")
  }

  render() {
    return (
        <button onClick={this.onClickHandler} id="button2">
            BUTTON2!!
        </button>
    )



 }
}

class Button1 extends React.Component {

  constructor(props){
    super(props)
    this.onClickHandler = this.onClickHandler.bind(this)
  }

  onClickHandler(){
    this.props.onClick('Button1')
  }

  render() {
    return (
        <button onClick={this.onClickHandler} id="button1">
            BUTTON1!!
        </button>
    )
  }
}

class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      showButton : true,
      hide: false
    }
    this.changeButtonState = this.changeButtonState.bind(this)
    this.getButton = this.getButton.bind(this)
    this.transitionEndEventName = this.transitionEndEventName.bind(this)
    this.hideApp = this.hideApp.bind(this)
    this.removeEvent = this.removeEvent.bind(this)
  }

  getButton() {
    if (this.state.showButton){
        return <Button1 onClick={this.hideApp}/>
      } else {
        return <Button2 onClick={this.hideApp}/>
      }
  }

  transitionEndEventName () {
    var el = document.createElement('div')//what the hack is bootstrap

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return transEndEventNames[name];
      }
    }

    return false // explicit for ie8 (  ._.)
}


  hideApp(button) {
    var app = document.getElementById('main')
    var transitionEnd = this.transitionEndEventName()
    app.addEventListener(transitionEnd, this.removeEvent, false)
        app.classList.contains('show-element') ? app.classList.remove('show-element') : null
        app.classList.add('remove-element')
  }

  removeEvent(){
    console.log('hey')
    var app = document.getElementById('main')
    var transitionEnd = this.transitionEndEventName()
    app.removeEventListener(transitionEnd, this.removeEvent, false)
    this.changeButtonState()
  }

  changeButtonState(button) {
    this.setState({
      showButton: !this.state.showButton,
      hide: true
    })
  }

  componentDidUpdate(){
    var app = document.getElementById('main')
    app.classList.contains('remove-element') ? app.classList.remove('remove-element') : null
    app.classList.add('show-element')
  }

  render(){
    var button = this.getButton()
    return (
        <div id="button-container">
            {button}
        </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('main'))

codepen (查看codepen