scrollIntoView 在第一次加载和每次刷新后不起作用

scrollIntoView does not work on first load and after each refresh

我在聊天中看到一个非常奇怪的行为。打开聊天后,只有当聊天中有图像时,滚动条才会向下移动一点点。当有只有text的时候,就一直往下走。此外,如果我关闭聊天并再次打开它,无论内容如何,​​滚动都会一直向下。但是,如果我刷新页面,滚动 returns 会出现奇怪的行为。我很困惑为什么会这样。这是我的代码:

聊天是这样开始的:

startChat () { 
       
    
    document.getElementById("myForm").style.display = "block";       
   
    
        const ref = firebase.firestore().collection('Chats').doc(this.state.uid).collection('Messages');

        const query = ref.orderBy('timestamp', 'desc').limit(10)



        this.unsubFromMessages = query.onSnapshot((snapshot) => {                            

                            if (snapshot.empty) {

                                console.log('No matching documents.');
                                
                                firebase.firestore().collection('Chats').doc(this.state.uid).
                                set({
                                    name: this.state.displayName,
                                    uid: this.state.uid,
                                    email: this.state.email
                                }).then(console.log("info saved"))
                                .catch((error) => {
                                    console.log("Error saving info to document: ", error);
                                });
                            }
                                                  
                                snapshot.docChanges().reverse().forEach((change) => {                                  
                                  

                                if (change.type === 'removed') {
                    
                                console.log(change.doc.data().content)
                    
                                } 
                                
                                
                                else if (change.type === 'added') {                
                                
                                  this.setState(state => {
                                    const messages = [...state.messages, {id: change.doc.id, body: change.doc.data()}]
                                    return {
                                        messages
                                    }
                    
                                })    
                                
                                setTimeout( this.scrollToBottom(), 2000)                                
                                
                                
                                
                                } 
                                
                                else if (change.type === 'modified') { 
                                    
                                                                        
                                    const filteredMessages = this.state.messages.filter(message => message.body.allowed === "yes")

                                   this.setState(state => {
                                      const messages = [...filteredMessages, {id: change.doc.id, body: change.doc.data()}]
                                      return {
                                          messages
                                      }
                      
                                  })    
                                  
                                  setTimeout( this.scrollToBottom(), 2000)
                                  
                                  
                                  
                                  } 
                    
                                                                  
                                });
                                }, (error) => {console.log(error)});             
                    
                                
    }

这是滚动功能:

scrollToBottom = () => {     

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

      }

这是聊天的 JSX:

<div className="form-popup" id="myForm">
                    <form className="form-container" onSubmit={this.chatFormSubmit}>

                        <h1>Chat</h1>

                        <label htmlFor="msg"><b>Message</b></label>


                        <div className="chatArea" id='messages'>
                            
                       
                            {
                               
                                this.state.messages.map((message, index) => {
                                return message.body.uid === this.state.uid && !message.body.imageUrl
                                ?
                                <p className="message-sent" key={index}>{message.body.content}</p>
                                : 
                                message.body.uid === this.state.uid && message.body.imageUrl 
                                ?
                                <img src={message.body.imageUrl} className="message-sent" key={index}></img>
                                :
                                <p className="message-received" key={index}>{message.body.content}</p>

                                    

                                
                                })
                            
                            }      

                            <div style={{ float:"left", clear: "both" }}
                               ref={this.myRef}>
                            </div>               
                           

                        </div>

如果关闭和向聊天提交消息的功能有任何用处,它们是:

closeForm() {
        document.getElementById("myForm").style.display = "none";
        this.setState({messages: []})
        this.unsubFromMessages();        
    }


chatFormSubmit(e) {
                  
        e.preventDefault();

        this.setState({ writeError: null }); 

        firebase.firestore()
        .collection('Chats')
        .doc(this.state.uid)
        .collection('Messages')  
        .doc()
        .set({
            docId: this.state.docId,
            content: this.chatArea.current.value,
            allowed: "yes",
            timestamp: new Date(),
            uid: this.state.uid,
            name: this.state.displayName,
            email: this.state.email
            }, { merge: true })
            .catch((error) => {
            this.setState({ writeError: error.message });
        })
            .then(this.chatArea.current.value = '')





    }

再一次,我自己弄明白了。与其在 setTimeout 中调用“this.scrollToBottom()”,不如像这样简单地传递它 setTimeout( this.scrollToBottom, 2000)。这就是为什么 setTimeout 不起作用并且滚动中途停止的原因。感谢 Felix Kling 在 中的评论。