【问题标题】:How to properly implement scrollHeight or scrollTop for div messages using Reactjs如何使用 Reactjs 正确实现 div 消息的 scrollHeight 或 scrollTop
【发布时间】:2020-07-28 05:36:52
【问题描述】:

我正在尝试在 Reactjs 中实现聊天消息。聊天消息被正确附加并且工作正常。

这是我的问题:聊天消息到达底部时不会向上滚动。

我正在考虑在消息到达底部时实现诸如聊天 div 自动向上滚动之类的功能。

scrollToBottom() {
  chat_messages.scrollTop = chat_messages.scrollHeight;
}

有什么解决方法吗?

代码如下:

<!DOCTYPE html>
<html>
   <head>

<style>

.chat_container{

background:blue;
height:40%;
max-height:40%;

width: 60%;
max-width: 60%;
 overflow-y: auto;

}


.chat_message{

background:green;
color:white;
padding:10px;
border:none;

}

.myFooter{
bottom:0px;
position:fixed;
background:red;
height:10%;
max-height:10%;

width: 60%;
max-width: 60%;


}
</style>
   </head>
   <body>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<script src="build/jquery.min.js"></script>

<div id="app"></div>

<script type="text/babel">


class Application extends React.Component {

//function Application() {
  constructor(props) {
    super(props);

const sender = 'John';

    this.state = {
message: '',
value: '',
sname: sender,
date: new Date(),
messages: []
};

this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  }

handleChange(event) {
    this.setState({message: event.target.value});
  }

  handleSubmit(event) {
   // alert('A name was submitted: ' + this.state.message);
    event.preventDefault();

const data = {'message': this.state.message}
 this.setState({
            messages : this.state.messages.concat([data])
        });
//$(".chat_container").animate({ scrollTop: 20000000 }, "slow");
 this.scrollToBottom();

  }



scrollToBottom() {
  chat_messages.scrollTop = chat_messages.scrollHeight;
}

componentDidMount() {
// fetch content axio or ajax
  }


  render() {

    return (
      <div>
        <div className="chat_container">


  <h2>Welcome to Chat: Time is: {this.state.date.toLocaleTimeString()}</h2>

      

 {this.state.messages.map((m, e) => (


              <div key={e}>


               
<div className="chat_message">chat: {m.message} ---{this.state.date.toLocaleTimeString()}</div> 

              </div>
            ))}

       
        </div>

<div className="myFooter">
 <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.message} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
</div>


      </div>
    );
  }
}


ReactDOM.render(<Application />, document.getElementById('app'));
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


   </body>
</html>

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    我得到了你的例子:

    bottomRef.current.scrollIntoView({ behavior: "smooth" });
    

    这是完整的代码;我很荣幸将它转换为一个功能性的 React 组件并使用了 useRef 钩子(滚动发生在消息状态更新的任何时候):

    import React, { useState, useRef, useEffect } from "react";
    import "./styles.css";
    
    export default function App(props) {
      const [message, setMessage] = useState("");
      const [messages, setMessages] = useState([]);
    
      const currentDate = new Date();
      const bottomRef = useRef();
    
      useEffect(() => {
        // fetch content axio or ajax
      }, []);
    
      useEffect(() => {
        bottomRef.current.scrollIntoView({ behavior: "smooth" });
      }, [messages]);
    
      function handleChange(event) {
        setMessage(event.target.value);
      }
    
      function handleSubmit(event) {
        // alert('A name was submitted: ' + this.state.message);
        event.preventDefault();
        const newMessages = messages;
        const data = { message: message, date: new Date() };
        setMessages(newMessages.concat([data]));
      }
    
      return (
        <React.Fragment>
          <h2>Welcome to Chat: Time is: {currentDate.toLocaleTimeString()}</h2>
    
          <div className="chat_container">
            {messages.map((m, e) => (
              <div key={e}>
                <div className="chat_message">
                  chat: {m.message} ---{m.date.toLocaleTimeString()}
                </div>
              </div>
            ))}
    
            <div id="bottom-reference" ref={bottomRef} />
          </div>
    
          <div className="myFooter">
            <form onSubmit={handleSubmit}>
              <label>
                Name:
                <input type="text" value={message} onChange={handleChange} />
              </label>
              <input type="submit" value="Submit" />
            </form>
          </div>
        </React.Fragment>
      );
    }
    

    我使用这些样式来测试滚动:

    .chat_container {
      height: 200px;
      overflow: scroll;
    }
    

    【讨论】:

    • 不错的方法。我所有的代码都已经在 Class 方法中了。我将模仿你的功能方法,看看它是如何进行的。感谢您的努力
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    相关资源
    最近更新 更多