初学前端对于大数据的展示

478 阅读7分钟

-   引言:大数据作为一股早已兴起的浪潮,正在对我们编程行业产生更加深刻的影响,无论是国家的政策还是市场的导向都给我们提供了更加丰富的机会和提出了更高的要求。作为前端人员,页面是根基,如何对大数据进行好的展示是一个值得好好研究的话题。下面我将解析一个简单的例子,给大家带来一些拙见。

正文:我们经常能在一些网站上看到一些新闻页面,一个页面上有很多栏新闻,用鼠标可以一直向下滚动,好像无穷无尽一般。

在这里有一个页面,有10000条“新闻“,假如每个“新闻“代表了一栏新闻,为了用户体验,每次在视窗只显示一部分新闻,可以上下滚动改变当前页面,且新闻顺序不变。

这是html文件的主要内容

下面是js文件解析。

首先,我们要存储1000条“新闻”,

此时有人可能会下意识地用for()循环来做,但这种写法很初级并且麻烦,会影响接下来的构造。另一种想法是使用数据库,无论是云数据还是传统的数据库。但存储的内容很少,且数据库的连接需要解决。所以在这里使用Array.from()这个函数,它会将我们的在10000条新闻存入内存,数据量不大,而且非常方便。在这里设置了一个常量originNews 代表原始新闻,用length直接设置了10000条数据,用字符串模板设置了每个key的value,这样就设置了每个“新闻”的内容。

第二步,用分页来实现滚动的显示效果,我们注意到首图中一个浏览器页面的新闻栏是有限的,并且分布平均。

首先我们设置了一个page代表页码,初始化为0代表第一页。它的作用稍后再叙。在此文的第一张图片中,可以注意到一共有15个“新闻”,pageNum代表的就是每个浏览器页面的新闻数量,用window.innerHeight获取到浏览器页面高度,我电脑上此值为727,在这里除以50是因为我设置了每个“新闻栏”的高度为50px。用Math.ceil()对结果向上取整,所以Math.ceil(727/50)=15。下面一段代码细看其实很简单的,这里设置了一个名为“chuck”的箭头函数,用于设置分页,这里的页不是浏览器页面,而是page,chuck让我们可以用page的值定位当前页,上一页,下一页。

如上图,chuck函数中我们传入了originNews和pageNum,分别传给了arr和size,所以我们可以计算出一些信息。chunck返回了一个分页新闻数组,即news.news的长度为10000/15的取上整数。而在后面news里的每个值其实是一个数组,我们可以看到用arr.slice()函数将原先的10000条“新闻”分成了一页页的新闻数组,每一页15条“新闻”。news成了下面要操作和显示的内容。

第三步,这是我们的核心,通过改变page的值,让我们滚动时的显示如同看书翻页一般,数据跟随着page的值被加载和显示。

这段代码中,hasPrepage和hasNextPage都是bool值,用来判断到前的page是否有前一页和后一页。回顾我们的第二步,我们初始化了page=0,如同于一本书的封面,没有前一页,news[news.length-1]则为新闻页的最后一页(注意下标),如同书的尾页。下面我们才真正设置了当前页,上一页,下一页。注意后两个都是相对的,需要判断条件来赋值。相应地被设置了为news[page +/- 1]。

第四步:开始真正滚动显示。滚动就像翻页,问题的核心在于我们怎样知道什么时候发生了翻页行为和当前在哪一页呢?只有知道了这些我们才能保持上下页的更新,使得浏览时保持顺序。首先我们捕捉翻页时间点。

这里,首先设置element获取页面所有class为news的元素,用于设置里面的显示。loadObserver才是我们的捕捉翻页行动。后面的IntersectionObserver()函数简单介绍一下,这是一个监听视窗的API,IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。构造函数的返回值是一个观察器实例。实例的observe方法可以指定观察哪个 DOM 节点。这里,我们IntersectionObserver()里的全部内容是回调函数。函数的参数entries是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。我们在这只监听了一个对象,即div中classs为news-footer的元素。但它的intersectionRatio>0时,表示它已经出现在我们浏览器页面的视窗中。如果不小于0,即表示没有达到这个页的底部,没有翻页,也就不做任何处理。

第五步,使新闻页在html里生成和显示。render函数接受两个参数,last用于判断是否到了当前页的最后一条"新闻"。data.forEach()用设置每个新闻的内容。用字符串模板设置data里每个class为news的div里的content,之前设置的originNews里的content都会传入。至于这个判断则是为了更好理解分页的思想,方便监控代码,news-href可以让我们看见每页的开始,因为当一条新闻是该页的最后一条也是下一页的开始,它的id会被设为news-href.

最后,我们来调用这个函数,将某个页的上一个页面的新闻数传入last,将上一页,当前页,下一页的数据放入函数中处理。... 是展开运算符,因为每个页包涵多条新闻,所以传入data的是一个二维数组。下面我们就真的捕捉了翻页这个事件了。此处逻辑为:判断当前的page中的尾部,entries中进入视窗的元素的类名为news-footer,即div中class为news-footer的元素出现在当前浏览页面中,或当前页为首页时,改变上一页和下一页的数据。所以当我们翻页时,上一页的数据会被保存,下一页的数据被加载,而且顺序是我们存储的新闻顺序。并不会改变。

看到这里,我们可能会迷惑,这到底是怎么分页的呢,这个上一页,当前页,下一页是什么呢?首先,我们知道,第一步和第二步让我们的10000条新闻存入内存,被分成Math.ceil(10000/15)页,每页15条新闻。这是物理上的分页,而我们的上一页,当前页,下一页是一个逻辑概念,每个物理上的页面都可以动态的变成三个中的任意一个,随着我们的翻页变化。到我们初进页面时,我们可以看到调试器的内容

在我们的浏览器页面显示的新闻为物理上的第0页,这一页没有上一页,有下一页,在header和footer中实际上包涵两页的数据,最后一页也是如此。通过第五步可知,我们可以理解为,每一次在html文件中有三页物理页的内容。每次滚动到三页中最后一页的底部时,div class=news-footer出现在浏览器页面中,函数会刷新里面的数据,让上,当前,下这逻辑上三页映射到新的物理页上。

  初写文章,见解片面,如有不妥,尽情指出。