【发布时间】:2017-04-05 10:26:39
【问题描述】:
我有一个 Vue 组件,其中包含多个元素。我想在调用组件中的方法时自动滚动到该元素的底部(基本上,与Scroll to bottom of div? 中的操作相同)。但是,我还没有找到在我的组件中获取元素并修改scrolTop
我目前正在使用 Vue 2.0.8
【问题讨论】:
标签: javascript vue.js
我有一个 Vue 组件,其中包含多个元素。我想在调用组件中的方法时自动滚动到该元素的底部(基本上,与Scroll to bottom of div? 中的操作相同)。但是,我还没有找到在我的组件中获取元素并修改scrolTop
我目前正在使用 Vue 2.0.8
【问题讨论】:
标签: javascript vue.js
据我了解,您想要的效果是在发生某些事情时滚动到列表(或可滚动的 div)的末尾(例如:将项目添加到列表中)。如果是这样,您可以仅使用纯 Javascript 和 VueJS 选择器滚动到容器元素的末尾(甚至是它自己的页面)。
var container = this.$el.querySelector("#container");
container.scrollTop = container.scrollHeight;
我在这个小提琴中提供了一个工作示例:https://jsfiddle.net/my54bhwn
每次将一个项目添加到列表中时,列表都会滚动到末尾以显示新项目。
希望对您有所帮助。
【讨论】:
this.$el.querySelector,你也可以通过ref机制选择你想要的div。
scrollToTop: false 才能在更改路线之间工作
window.scrollTo(0, document.body.scrollHeight); ?
el.scrollIntoView()
这个解决方案不会伤害你的大脑,不必考虑scrollTop 或scrollHeight,内置平滑滚动,甚至可以在 IE 中使用。
scrollIntoView() 有一些选项,您可以像scrollIntoView({behavior: 'smooth'}) 一样传递它以获得平滑滚动。
methods: {
scrollToElement() {
const el = this.$refs.scrollToMe;
if (el) {
// Use el.scrollIntoView() to instantly scroll to the element
el.scrollIntoView({behavior: 'smooth'});
}
}
}
如果你想在页面加载时滚动到这个元素,你可以这样调用这个方法:
mounted() {
this.scrollToElement();
}
否则,如果您想在单击按钮或其他操作时滚动到它,您可以用相同的方式调用它:
<button @click="scrollToElement">scroll to me</button>
滚动一直有效到 IE 8。平滑滚动 效果在 IE 或 Safari 中无法开箱即用。如果需要,可以在 cmets 中提到 @mostafaznv 的 polyfill available for this here。
【讨论】:
我尝试了公认的解决方案,但它对我不起作用。我使用浏览器调试器发现应该使用的实际高度是clientHeight 但是你必须把它放到updated() 钩子中才能使整个解决方案工作。
data(){
return {
conversation: [
{
}
]
},
mounted(){
EventBus.$on('msg-ctr--push-msg-in-conversation', textMsg => {
this.conversation.push(textMsg)
// Didn't work doing scroll here
})
},
updated(){ <=== PUT IT HERE !!
var elem = this.$el
elem.scrollTop = elem.clientHeight;
},
【讨论】:
$nextTick() 的回调。这将产生相同的效果,但可能需要的资源要少得多。
scrollToTop: false 才能在更改路线之间工作
ref 属性作为参考<div class="content scrollable" ref="msgContainer">
<!-- content -->
</div>
data() {
return {
count: 5
};
},
watch: {
count: function() {
this.$nextTick(function() {
var container = this.$refs.msgContainer;
container.scrollTop = container.scrollHeight + 120;
});
}
}
.scrollable {
overflow: hidden;
overflow-y: scroll;
height: calc(100vh - 20px);
}
【讨论】:
这是一个使用ref 滚动到div 底部的简单示例。
/*
Defined somewhere:
var vueContent = new Vue({
el: '#vue-content',
...
*/
var messageDisplay = vueContent.$refs.messageDisplay;
messageDisplay.scrollTop = messageDisplay.scrollHeight;
<div id='vue-content'>
<div ref='messageDisplay' id='messages'>
<div v-for="message in messages">
{{ message }}
</div>
</div>
</div>
请注意,通过在 HTML 中添加 ref='messageDisplay',您可以通过 vueContent.$refs.messageDisplay 访问该元素
【讨论】:
如果需要支持 IE11 和(旧)Edge,可以使用:
scrollToBottom() {
let element = document.getElementById("yourID");
element.scrollIntoView(false);
}
如果你不需要支持IE11,下面的就可以了(代码更清晰):
scrollToBottom() {
let element = document.getElementById("yourID");
element.scrollIntoView({behavior: "smooth", block: "end"});
}
【讨论】:
在您发布的相关问题中,我们已经有一种方法可以在纯 javascript 中实现这一点,因此我们只需要获取对我们要滚动的 dom 节点的 js 引用。
The ref attribute 可用于声明对 html 元素的引用,以使它们在 vue 的组件方法中可用。
或者,如果method in the component 是某个 UI 事件的处理程序,并且目标与您要在空间中滚动的 div 相关,您可以简单地将 pass in the event object 连同您想要的参数一起,然后像滚动scroll(event.target.nextSibling).
【讨论】:
试试vue-chat-scroll:
通过 npm 安装:npm install --save vue-chat-scroll
进口:
import Vue from 'vue'
import VueChatScroll from 'vue-chat-scroll'
Vue.use(VueChatScroll)
在 app.js 之后 window.Vue = require('vue').default;
然后使用它:
<ul class="messages" v-chat-scroll>
// your message/chat code...
</ul>
【讨论】:
我的应用程序也有同样的需求(具有复杂的嵌套组件结构),但遗憾的是我没有成功使其工作。
最后我使用了vue-scrollto,效果很好!
【讨论】:
该解决方案对我不起作用,但以下代码对我有用。我正在处理 message-box 类的动态项目。
scrollToEnd() {
setTimeout(() => {
this.$el
.getElementsByClassName("message-box")
[
this.$el.getElementsByClassName("message-box").length -
1
].scrollIntoView();
}, 50);
}
记得将方法放在mounted() 而不是created() 中,并将message-box 类添加到动态项中。 setTimeout() 是这项工作必不可少的。您可以参考https://forum.vuejs.org/t/getelementsbyclassname-and-htmlcollection-within-a-watcher/26478了解更多信息。
【讨论】:
对于那些还没有找到上述可行解决方案的人,我相信我有一个可行的解决方案。我的具体用例是,每当向数组添加新消息时,我想滚动到特定 div 的底部——在我的例子中是一个聊天框。
const container = this.$el.querySelector('#messagesCardContent');
this.$nextTick(() => {
// DOM updated
container.scrollTop = container.scrollHeight;
});
我必须使用 nextTick,因为我们需要等待 dom 从数据更改中更新,然后再进行滚动!
我只是将上面的代码放在消息数组的观察器中,如下所示:
messages: {
handler() {
// this scrolls the messages to the bottom on loading data
const container = this.$el.querySelector('#messagesCard');
this.$nextTick(() => {
// DOM updated
container.scrollTop = container.scrollHeight;
});
},
deep: true,
},
【讨论】:
这对我有用
this.$nextTick(() => {
let scrollHeight = this.$refs.messages.scrollHeight
window.scrollTo(0, scrollHeight)
})
【讨论】:
我的解决方案没有模块:
模板
<div class="scrollable-content" ref="conversations" />
脚本
scrollToBottom() {
const container = this.$refs.conversations;
container.scrollTop = container.scrollHeight;
},
【讨论】: