Javascript Vue页面没有';装载时不要向下滚动
我很难在加载时使页面向下滚动到最新消息。我有同样的功能,当一个人发送一条新消息时,页面会在发送后直接向下滚动到最新消息。 我尝试了一些方法,比如scrollIntoView,甚至将scrollTop设置为9999。但是,当我在控制台上记录scrollTop时,它仍然指示它为0。在创建消息后,在mounted中调用该函数。 有谁能帮助我为什么它不工作?非常感谢你的帮助,谢谢Javascript Vue页面没有';装载时不要向下滚动,javascript,html,firebase,vue.js,dom,Javascript,Html,Firebase,Vue.js,Dom,我很难在加载时使页面向下滚动到最新消息。我有同样的功能,当一个人发送一条新消息时,页面会在发送后直接向下滚动到最新消息。 我尝试了一些方法,比如scrollIntoView,甚至将scrollTop设置为9999。但是,当我在控制台上记录scrollTop时,它仍然指示它为0。在创建消息后,在mounted中调用该函数。 有谁能帮助我为什么它不工作?非常感谢你的帮助,谢谢 <v-container> <div id="top-nav"> &
<v-container>
<div id="top-nav">
<v-avatar id="avatar">
<img src="../../public/img/icons/myavatar.png" alt="avatar">
</v-avatar>
<div id="title-grp">
<h3 id="sofia-title">Sofia</h3>
<div id="online-grp">
<span id="online-circle"></span>
<p id="online-text">Online</p>
</div>
</div>
</div>
<div id="msg-container">
<v-row dense>
<v-col cols="12">
<v-card
style="width: fit-content"
v-for="(message,index) in messages"
:key="index"
:style="{'margin-left': message.isRobot ? '' : 'auto'}"
:color="message.isRobot? '#F5F3FF' :'#C66BCC'"
id="convo-space"
>
<p id="timestamp" :style="{'color': message.isRobot? '#808080' : '#000000'}">{{message.timestamp}}</p>
<v-card-text
:style="{'color': message.isRobot ? 'black' : 'white', 'font-size': '16px'}"
>
{{message.text}}
</v-card-text>
</v-card>
<div id="bottom-scroll" ref="last-message"></div>
</v-col>
</v-row>
</div>
<div id="bottom-container">
<div class="col-text">
<input type="text" placeholder="Type here" id="text-input" v-model="userMessage">
</div>
<div class="col-btn">
<button @click="sendMessage" id="btn-color-text"> Send </button>
</div>
</div>
</v-container>
</template>
<script>
import {config} from "../config.js"
const token = config.dialogflow.clientBot;
import { ApiAiClient } from 'api-ai-javascript';
const client = new ApiAiClient({accessToken: token});
import { mapGetters } from "vuex";
import firebase from "firebase";
export default {
data: () => ({
messages: [],
userMessage: "",
}),
methods: {
sendMessage(){
var timestamp = new Date().toLocaleTimeString(undefined, {hour: '2-digit', minute: '2-digit'});
const usrMessage = {
text: this.userMessage,
isRobot: false,
timestamp: timestamp
};
this.messages.push(usrMessage);
client.textRequest(this.userMessage).then((response) => {
const robotMessage = {
text: response.result.fulfillment.speech,
isRobot: true,
timestamp: timestamp
};
firebase
.firestore()
.collection("users")
.doc(firebase.auth().currentUser.uid)
.collection("messages")
.add({
userMessage: usrMessage.text,
robotMessage: robotMessage.text,
timestamp: timestamp
});
const delay = ms => new Promise(res => setTimeout(res,ms));
const pushMsg = async () => {
let randNum = Math.floor(Math.random() * 8000);
await delay(randNum);
await this.messages.push(robotMessage);
this.scrollToEnd();
};
pushMsg();
this.scrollToEnd();
});
this.userMessage = "";
console.log(firebase.auth().currentUser.uid);
},
scrollToEnd(){
var container = this.$el.querySelector('#msg-container');
container.scrollTop = container.scrollHeight;
console.log(container.scrollHeight);
console.log(container.scrollTop);
}
},
created(){
var oldMessages = [];
firebase
.firestore()
.collection("users")
.doc(firebase.auth().currentUser.uid)
.collection("messages")
.get()
.then( (querySnapshot) => {
querySnapshot.forEach(function(doc){
var snapMsg = doc.data();
let robot = {
text: snapMsg.robotMessage,
timestamp: snapMsg.timestamp,
isRobot: true
}
let human = {
text: snapMsg.userMessage,
timestamp: snapMsg.timestamp,
isRobot: false
}
oldMessages.unshift(human, robot);
});
this.messages = oldMessages;
});
},
mounted(){
var bottomDiv = this.$el.querySelector('#bottom-scroll');
bottomDiv.scrollIntoView();
console.log(bottomDiv);
console.log(bottomDiv.scrollIntoView());
// var bottomDiv = this.$el.querySelector('#msg-container');
// bottomDiv.scrollTop = 9999;
// console.log(bottomDiv.scrollTop);
navigator.serviceWorker.addEventListener('message', (e) => {
console.log('Push Notification received');
console.log(e.data.firebaseMessagingData.notification.body);
var timestamp = new Date().toLocaleTimeString(undefined, {hour: '2-digit', minute: '2-digit'});
const robotMessage = {
text: e.data.firebaseMessagingData.notification.body,
isRobot: true,
timestamp: timestamp
}
firebase
.firestore()
.collection("users")
.doc(firebase.auth().currentUser.uid)
.collection("messages")
.add({
robotMessage: robotMessage.text,
timestamp: robotMessage.timestamp
});
this.messages.push(robotMessage);
});
},
computed: {
...mapGetters({
user: "user"
})
}
}
</script> ```
索非亚
在线
{{message.timestamp}
{{message.text}
发送
从“./config.js”导入{config}
const token=config.dialogflow.clientBot;
从“api ai javascript”导入{APAIClient};
const client=new apaiclient({accessToken:token});
从“vuex”导入{mapGetters};
从“firebase”导入firebase;
导出默认值{
数据:()=>({
信息:[],
用户消息:“”,
}),
方法:{
sendMessage(){
var timestamp=new Date();
常量usrMessage={
text:this.userMessage,
以色列机器人:错,
时间戳:时间戳
};
this.messages.push(usrMessage);
client.textRequest(this.userMessage).then((response)=>{
const robotMessage={
文本:response.result.fulfillment.speech,
是的,
时间戳:时间戳
};
火基
.firestore()
.收集(“用户”)
.doc(firebase.auth().currentUser.uid)
.收集(“信息”)
.添加({
userMessage:usrMessage.text,
robotMessage:robotMessage.text,
时间戳:时间戳
});
const delay=ms=>newpromise(res=>setTimeout(res,ms));
const pushMsg=async()=>{
设randNum=Math.floor(Math.random()*8000);
等待延迟(randNum);
等待。消息。推送(机器人消息);
这个.scrollToEnd();
};
pushMsg();
这个.scrollToEnd();
});
this.userMessage=“”;
log(firebase.auth().currentUser.uid);
},
scrollToEnd(){
var container=this.$el.querySelector(“#msg container”);
container.scrollTop=container.scrollHeight;
console.log(container.scrollHeight);
console.log(container.scrollTop);
}
},
创建(){
var oldMessages=[];
火基
.firestore()
.收集(“用户”)
.doc(firebase.auth().currentUser.uid)
.收集(“信息”)
.get()
.然后((querySnapshot)=>{
querySnapshot.forEach(函数(doc){
var snapMsg=doc.data();
让机器人={
文本:snapMsg.robotMessage,
时间戳:snapMsg.timestamp,
以色列机器人:是的
}
让人类={
文本:snapMsg.userMessage,
时间戳:snapMsg.timestamp,
isRobot:false
}
旧消息。取消移动(人类、机器人);
});
this.messages=旧消息;
});
},
安装的(){
var bottomDiv=this.$el.querySelector(“#底部滚动”);
bottomDiv.scrollIntoView();
控制台日志(bottomDiv);
log(bottomDiv.scrollIntoView());
//var bottomDiv=this.$el.querySelector(“#msg container”);
//bottomDiv.scrollTop=9999;
//控制台日志(bottomDiv.scrollTop);
navigator.serviceWorker.addEventListener('message',(e)=>{
log(“收到推送通知”);
日志(e.data.firebaseMessagingData.notification.body);
var timestamp=new Date();
const robotMessage={
文本:e.data.firebaseMessagingData.notification.body,
是的,
时间戳:时间戳
}
火基
.firestore()
.收集(“用户”)
.doc(firebase.auth().currentUser.uid)
.收集(“信息”)
.添加({
robotMessage:robotMessage.text,
时间戳:robotMessage.timestamp
});
this.messages.push(robotMessage);
});
},
计算:{
…地图绘制者({
用户:“用户”
})
}
}
```
发生的情况是,当数据已更新而DOM尚未更新时,您正试图更新UI。当使用nextTick更新Dom/Ui时,调用scrollToEnd
,每当Dom更新时,都会调用vue nextTick
例如,您的代码
const pushMsg = async () => {
let randNum = Math.floor(Math.random() * 8000);
await delay(randNum);
await this.messages.push(robotMessage);
this.scrollToEnd();
};
应该是
let self= this;
const pushMsg = async () => {
let randNum = Math.floor(Math.random() * 8000);
await delay(randNum);
await this.messages.push(robotMessage);
self.$nextTick(function(){
this.scrollToEnd();
})
};
嘿,艾曼纽,谢谢你的回答。我试图实现你的建议,但似乎仍然不起作用:(检查,谢谢,伙计。它现在似乎起作用了。我在挂载中实现了nextTick,但不起作用。所以我看到了你的代码,你将nextTick放入了watched中,最后它起作用了。谢谢@emmanuel!@AhmadNurhadi不客气,请将其作为答案投票