Javascript 如何在新帖子以反应方式呈现时保持滚动位置?
假设我正在渲染一堆帖子Javascript 如何在新帖子以反应方式呈现时保持滚动位置?,javascript,meteor,meteor-blaze,Javascript,Meteor,Meteor Blaze,假设我正在渲染一堆帖子 {{#each posts}} {{>post}} {{/each}} 我收到了一堆按日期排序的帖子 Posts.find({}, {sort:{name: 1, date:-1}, limit: Session.get('limit')}).fetch() 我这里有一些反应性的滚动,正如你从移动应用程序中所期望的那样。但现在的问题是,当有人发布新内容时,一切都会发生变化。我的滚动位置保持不变,但我不再看同一篇文章 你有什么办法让它工作吗 编辑: 在我看来,
{{#each posts}}
{{>post}}
{{/each}}
我收到了一堆按日期排序的帖子
Posts.find({}, {sort:{name: 1, date:-1}, limit: Session.get('limit')}).fetch()
我这里有一些反应性的滚动,正如你从移动应用程序中所期望的那样。但现在的问题是,当有人发布新内容时,一切都会发生变化。我的滚动位置保持不变,但我不再看同一篇文章
你有什么办法让它工作吗
编辑:
在我看来,最优雅的解决方案是将我们对滚动的想法颠倒过来。如果我们以另一种方式对帖子进行排序——最老的在顶部,那么新的帖子将在底部结束,不会弄乱scrollTop的位置
编辑2:
我忘了提到--我不知道要插入的元素的高度。否则我可以接受和。好吧,我也遇到了同样的问题,下面是我提出的粗略解决方案。如果你发现有洞就告诉我
Template.postsList.rendered = function (){
this.find('.wrapper')._uihooks = {
insertElement: function (node, next){
//hide newly added element, add a class to identify it as a post inserted
//after initial load.
$(node).hide().insertBefore(next).addClass('insertedAfterLoad');
//if it's at the top of the page, fade it in, otherwise it will stay hidden
if (getDistance() === 0){
$(node).fadeIn();
}
}
},
//Continually watch the page while scrolling
$(document).scroll(function(){
var scrollDistance = getDistance();
//if any posts have the 'insertedAfterLoad' class, fade them into view.
//this will only load new posts if the user scrolls back to the top
if( scrollDistance === 0 && $('.post').hasClass('insertedAfterLoad') ){
$('.insertedAfterLoad').fadeIn();
}
});
//This will get the distance to the top of the page of any elements
//inserted after the initial page load
var getDistance = function(){
if( $('.post').hasClass('insertedAfterLoad') ){
return $('.insertedAfterLoad').offset().top;
}
}
}
我对你真正想做什么有些困惑,但是如果你想在底部有新的帖子并滚动到它们,你可以做一些类似于我在这篇使用Meteor的文章中所做的事情 首先,将scrollTo包添加到meteor应用程序中
$ meteor add natestrauser:jquery-scrollto
在用于将帖子从表单提交到集合的模板事件中,添加带有scrollTo
的setTimeout函数,该函数将在新帖子添加到集合后几毫秒内触发,并将滚动到新帖子:
Template.posts.events({
"submit .new-post": function (event) {
var title = event.target.postTitle.value;
var text = event.target.postText.value;
Posts.insert({
title: title,
text: text,
date: new Date() // current time
});
setTimeout(function(){
$(".posts-wrapper").scrollTo("max", 500); // change 500 miliseconds to whatever speed you want
}, 100);
// Clear form
event.target.postTitle.value = "";
event.target.postText.value = "";
// Prevent default form submit
return false;
}
});
模板助手,用于获取帖子、进行排序等:
Template.posts.helpers({
posts: function() {
return Posts.find({}).fetch;
}
});
带有表单的模板,用于添加帖子以及在类为的div
中呈现的帖子。帖子包装器
:
<template name="posts">
<form class="new-post">
<label>Post title: </label>
<input type="text" name="postTitle">
<label>Post text: </label>
<input type="textarea" name="postText">
</form>
<div class="posts-wrapper">
{{#each posts}}
{{> post}}
{{/each}}
</div>
</template>
这里只是头脑风暴,但是如果您使用collection hooks包,您可以在scrollTo after Posts.find()函数上触发它。可能是一种更简单的方法。我考虑过使用
光标。观察,但这是一种巨大的痛苦,我相信它会有一些效果。查看我的编辑--太长了,这里有一种方法可以做到,就是让帖子从顶部滑入(即从高度0到500px),同时让页面以与帖子滑入相同的速度滚动(即让帖子滑入650ms以上,也滚动650ms以上)是的,但还有一个问题我应该提一下——我不知道我插入的元素的高度……你可以使用javascript来获取元素的高度,我知道你可以用jQuery来确定有一个本地JS等价物。可能是,实际上是身高
setTimeout(function(){
$("body").scrollTo("max", 500); // change 500 miliseconds to whatever speed you want
}, 100);