如何使用新的Firebase(2016)实现无限滚动?

题:

如何使用JavaScript(和node.js)在Firebase中实现高效的无限滚动?


我检查了什么:

使用Firebase实现无限滚动?

问题:老火炉^

无限滚动与AngularJs和Firebase


代码来自: AngularJs和Firebase的无限滚动

“首先,我build议在您的Firebase中创build一个索引,为此我创build了这个索引:

{ "rules": { ".read": true, ".write": false, "messages": { ".indexOn": "id" } } } 

然后,让我们用Firebase制作一些魔法:

 // @fb: your Firebase. // @data: messages, users, products... the dataset you want to do something with. // @_start: min ID where you want to start fetching your data. // @_end: max ID where you want to start fetching your data. // @_n: Step size. In other words, how much data you want to fetch from Firebase. var fb = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/'); var data = []; var _start = 0; var _end = 9; var _n = 10; var getDataset = function() { fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) { data.push(dataSnapshot.val()); }); _start = _start + _n; _end = _end + _n; } 

最后,更好的无限滚动(无jQuery):

 window.addEventListener('scroll', function() { if (window.scrollY === document.body.scrollHeight - window.innerHeight) { getDataset(); } }); 

我在React中使用这种方法,不pipe你的数据有多大,它都是快速的。“

(回答15年2月26日在15:02)

(由Jobsamuel)


问题

在该解决scheme中,每次滚动达到屏幕高度的末端时,将加载n个post。

根据屏幕尺寸的不同,这意味着在某个时间点将会加载比需要更多的post(屏幕高度只包含2个post,这意味着每当我们到达屏幕高度的末尾时,例如= 5)。

这意味着3*NumberOfTimesScrollHeightHasBeenPassed比需要更多的post将被加载,每次我们到达scrollHight结束。


我目前的代码(一次加载所有文章,没有无限滚动):

 var express = require("express"); var router = express.Router(); var firebase = require("firebase"); router.get('/index', function(req, res, next) { var pageRef = firebase.database().ref("posts/page"); pageRef.once('value', function(snapshot){ var page = []; global.page_name = "page"; snapshot.forEach(function(childSnapshot){ var key = childSnapshot.key; var childData = childSnapshot.val(); page.push({ id: key, title: childData.title, image: childData.image }); }); res.render('page/index',{page: page}); }); }); 

这里是无限分页的完整代码。

函数createPromiseCallback用于支持promise和callback。

 function createPromiseCallback() { var cb; var promise = new Promise(function (resolve, reject) { cb = function (err, data) { if (err) return reject(err); return resolve(data); }; }); cb.promise = promise; return cb; } 

函数getPaginatedFeed实现实际的分页

 function getPaginatedFeed(endpoint, pageSize, earliestEntryId, cb) { cb = cb || createPromiseCallback(); var ref = database.ref(endpoint); if (earliestEntryId) { ref = ref.orderByKey().endAt(earliestEntryId); } ref.limitToLast(pageSize + 1).once('value').then(data => { var entries = data.val() || {}; var nextPage = null; const entryIds = Object.keys(entries); if (entryIds.length > pageSize) { delete entries[entryIds[0]]; const nextPageStartingId = entryIds.shift(); nextPage = function (cb) { return getPaginatedFeed(endpoint, pageSize, nextPageStartingId, cb); }; } var res = { entries: entries, nextPage: nextPage }; cb(null, res); }); return cb.promise; } 

这里是如何使用getPaginatedFeed函数

 var endpoint = '/posts'; var pageSize = 2; var nextPage = null; var dataChunk = null; getPaginatedFeed(endpoint, pageSize).then(function (data) { dataChunk = data.entries; nextPage = data.nextPage; //if nexPage is null means there are no more pages left if (!nextPage) return; //Getting second page nextPage().then(function (secondpageData) { dataChunk = data.entries; nextPage = data.nextPage; //Getting third page if (!nextPage) return; nextPage().then(function (secondpageData) { dataChunk = data.entries; nextPage = data.nextPage; //You can call as long as your nextPage is not null, which means as long as you have data left }); }); }); 

怎么样的问题放在屏幕上,你可以给这样的解决scheme,为每个职位给定的x高度,如果它需要更多的空间把“读更多”链接的post底部,这将显示失踪用户点击的部分。 在这种情况下,您可以保持屏幕上的项目固定计数。 此外,您可以检查屏幕分辨率,以放置更多或更less的项目。