[英]How to scroll to bottom of div when new elements are added
我正在尝试使用 Vue 和 Express 制作聊天应用程序。
目前,我想让带有消息的容器在发送新消息时自动滚动到底部。 我尝试通过使用选择 div 容器并将其scrollHeight
分配给scrollTop
的scrollToEnd
函数来做到这一点:
scrollToEnd: function () {
var messages = this.$el.querySelector('#messages')
messages.scrollTop = messages.scrollHeight
}
这给出了以下错误:
TypeError:无法读取 null 的属性“scrollHeight”
出于某种原因,使用querySelector
总是返回 null,当我在其他元素上测试它时也是如此。
可以在下面找到该组件的完整代码。
<template>
<div id="messages">
<ul>
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</div>
</template>
<script>
import MessageService from '@/services/MessageService'
export default {
name: 'messages',
data () {
return {
messages: []
}
},
mounted () {
this.getMessages()
this.$root.$on('newMessage', (msg) => {
this.message = msg
this.getMessages()
this.scrollToEnd()
})
},
methods: {
async getMessages () {
const response = await MessageService.fetchMessages()
this.messages = response.data.messages
},
scrollToEnd: function () {
var messages = this.$el.querySelector('#messages')
messages.scrollTop = messages.scrollHeight
}
}
}
</script>
this.$el
Vue 实例管理的根 DOM 元素。
this.$el
是#messages
div,无需从DOM 中获取它。
然后,您可以使用this.$el.lastElementChild.offsetTop
来获取最后一条消息并滚动到它的顶部,所以如果它很长,您就不会滚动超过它的起点。
在这里,我稍微简化了模板以使其直截了当。
<template>
<ul id="messages">
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</template>
<script>
export default {
name: 'messages',
data() {
return { messages: [] };
},
mounted() {
this.getMessages();
},
updated() {
// whenever data changes and the component re-renders, this is called.
this.$nextTick(() => this.scrollToEnd());
},
methods: {
async getMessages () {
// ...snip...
},
scrollToEnd: function () {
// scroll to the start of the last message
this.$el.scrollTop = this.$el.lastElementChild.offsetTop;
}
}
}
</script>
如果你真的想保留<div>
容器,你可以使用ref
。
<template>
<div id="messages">
<ul ref="list">
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</div>
</template>
然后在组件中,你可以通过this.$refs.list
来引用它。
ref
用于注册对元素或子组件的引用。 该引用将注册在父组件的$refs
对象下。 如果在普通 DOM 元素上使用,则引用将是该元素; 如果在子组件上使用,引用将是组件实例。
虽然 Vue 示例经常使用原生 DOM API 来解决问题,但在这种情况下使用ref
更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.