2016-02-23 7 views
9

Ich schreibe eine einfache "Konsole", die Nachrichten in einer Chat-ähnlichen Weise zeigt. Die Nachrichten erscheinen von unten und bewegen sich nach oben.velocity-react - animieren scrollTop nach Komponenten-Update

Ich habe den Arbeitscode, aber ich möchte die erscheinenden Nachrichten animieren, indem ich den Container jedes Mal nach unten scrolle, wenn ein neues "li" hinzugefügt wird.

Aktuelle Code:

import React from 'react'; 
import { render, findDOMNode } from 'react-dom'; 


export default React.createClass({ 
    componentDidUpdate : function(){ 
     var node = findDOMNode(this); 
     node.scrollTop = node.scrollHeight; 
    }, 
    render() { 
     return (
      <ul id="log"> 
      { 
       this.props.messages.map(function(message, index){ 
        return <li key={index}>[{message.time.format('HH:mm:ss')}] {message.action}</li> 
       }) 
      } 
      </ul> 
     ) 
    } 
}) 

Die messages prop kommt von der übergeordneten Komponente und dem Laden.

Ich fand dieses Geschwindigkeit Plugin: https://github.com/twitter-fabric/velocity-react und ich kann nicht herausfinden, wie man es in meiner Situation verwendet. Alle Beispiele scheinen nicht zu gelten (oder ich verstehe sie einfach nicht).

Ich bin ziemlich neu zu reagieren, und einige Konzepte verwirren mich immer noch, also bitte verstehen.

Ich möchte nicht jQuery verwenden.

+0

so bekam u die reagieren Teil arbeiten und u r pur suchen E js Scrollen? – goldylucks

+0

Ja, der obige Code funktioniert. Ich möchte die Schriftrolle animieren. Ich weiß, wie man das mit jQuery macht, aber das Hinzufügen von jQuery zum reagieren fühlt sich dumm an. Mittlerweile entgehen React-Animations-Plugins meinem Verständnis. Ich habe vorher "reine" Geschwindigkeit verwendet, und ich weiß, wie leistungsfähig es ist. Es wäre schön, es in React verwenden zu können. Die Frage ist also praktisch die Geschwindigkeit js, aber ich bin offen für andere Vorschläge. –

+0

ein genauerer Titel würde b: "Javascript Scroll-Animation ohne jquery"; was würde dir hier gebracht haben: http://stackoverflow.com/questions/8917921/cross-browser-javascript-not-jquery-scroll-to-top-animation – goldylucks

Antwort

3

Das Plugin velocity-react bietet bereits implementierte React-Komponenten für die Verwendung der Velocity-Animationen.

Ich denke, dass die Scroll-Funktionalität kann auch über Animationen implementiert werden, aber Velocity-Bibliothek hat scroll command. Ich habe das velocity-react Plugin erkannt und es stellt eine Schnittstelle (Komponenten) für die Animationen zur Verfügung. Es gibt keine Unterstützung für die Velocity-Befehle.

Es ist ziemlich einfach Velocity-Befehle in React zu verwenden. Ich habe react-velocity-scroll Repo basierend auf Ihrer Frage erstellt und es gibt eine Live-Demo von Senden/Auflisten von Nachrichten in einer Chat-ähnlichen Weise.

Bitte beachten Sie, dass die Velocity-Bibliothek im Beispiel über das velocity-react-Plugin enthalten ist. Es wird empfohlen, das Plugin für zukünftige fortgeschrittene Animationen zu verwenden, da es bereits implementierte React-Komponenten für die Verwendung der Velocity-Animationen bietet. Das Repo verwendet jedoch keine Animationen. Es verwendet nur den Scroll-Befehl der Velocity-Bibliothek. Wenn Sie möchten, können Sie die Velocity-Bibliothek unabhängig importieren.

Allerdings sind hier meine Komponenten. Bitte konzentrieren Sie sich auf MessageItem Komponente - sobald eine neue Nachricht hinzugefügt wird, dann scrollen Sie nach unten.

App

import React from 'react'; 
import MessagesList from './MessagesList'; 

const style = { 
    textAlign: 'center' 
}; 

class App extends React.Component{ 
    constructor(props) { 
     super(props); 

     this.state = { 
      /** 
      * @type Array - Store sent messages 
      */ 
      messages: [], 
      /** 
      * @type String - Store the input value. 
      * It's reset on message sent 
      */ 
      text: '' 
     } 
    } 

    handleOnChange(e) { 
     const text = e.target.value; 
     this.setState({ text }); 
    } 

    handleOnKeyPress(e) { 
     const text = e.target.value; 

     // Send the message on `Enter` button press 
     if (e.key === 'Enter') { 
      this.sendMessage(text); 
     } 
    } 

    /** 
    * Add the message to the state and reset the value 
    * of the input 
    * 
    * @param String text - Message text 
    */ 
    sendMessage(text) { 
     const { messages } = this.state; 
     const message = { date: new Date(), text }; 

     this.setState({ 
      messages: messages.concat([message]), 
      text: '' 
     }); 
    } 

    render() { 
     const { messages, text } = this.state; 

     return <div style={style}> 
      <h1>Please enter your text message:</h1> 

      <input 
       value={text} 
       placeholder="Press Enter for sending" 
       onChange={this.handleOnChange.bind(this)} 
       onKeyPress={this.handleOnKeyPress.bind(this)} /> 

      <MessagesList messages={messages} /> 
     </div> 
    } 
} 

export default App; 

MessagesList

import React from 'react'; 
import MessageItem from './MessageItem'; 

const style = { 
    height: '100px', 
    overflowY: 'scroll' 
}; 

const MessagesList = (props) => { 
    let { messages } = props; 

    messages = messages.map(function(message, index){ 
     return <MessageItem key={index} index={index} message={message} /> 
    }); 

    return <ul style={style}>{messages}</ul> 
}; 

export default MessagesList; 

MessageItem

import React from 'react'; 
import ReactDOM from 'react-dom'; 
const Velocity = require('../node_modules/velocity-react/lib/velocity-animate-shim'); 

const style = { 
    listStyle: 'none' 
}; 

class MessageItem extends React.Component{ 
    componentDidMount() { 
     const parentNode = ReactDOM.findDOMNode(this).parentNode; 
     const node = ReactDOM.findDOMNode(this); 

     // Once a new item is being added, then scroll down to it 
     Velocity(node, 'scroll', { 
      duration: 500, 
      container: parentNode, 
      queue: false 
     }); 
    } 

    render() { 
     const { message } = this.props; 

     return <li style={style}>{message.date + ' - ' + message.text}</li> 
    } 
} 

export default MessageItem; 
Verwandte Themen