你的位置:首页 > Java教程

[Java教程]从273二手车的M站点初探js模块化编程


前言

      这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式。也就说分为大分页和小分页两种交互。大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数据。

      273这个M站点是产品推荐我看的。第一眼看这个产品时我就再想他们这个三次加载和翻页按钮的方式,那么小分页的pageIndex是怎么计算的。所以就顺便看了下源码。 提到看源码时用到了Chrome浏览器的格式化工具(还是朋友推荐我的,不过这个格式化按钮的确不明显,不会的话自行百度)。

 

三次加载和分页思路分析

 

 

 

    1、从页面最底部的分页数量来看,只设置了25页而不是随着翻页数量的变化而动态设置,也就是说只能看到最新的25页数据。再换句话说这里的分页数量是固定死的,无法查看历史数据。

    2、从第一张图中可以看出,每页的首屏数据是【同步的方式加载】。

    3、从第三张图中可以看出,当你第二次下拉和第三次下拉时从右边的报文中看出,第二次和第三次分别是【异步刷新】加载数据。在NetWork中看出,异步加载数据时请求ajax.php?module=getCarSalePost. POST请求。重点就在POST请求的数据上。 第二次请求的POST数据:page:2、filter:/car/、need_bak。

 

异步记载数据时page是怎么计算的?

      filter不用说是大分页每次的页码和其他附加条件。need_bak没搞懂是什么参数。OK,那看到这里无非就是搞清楚这个page是怎么计算的,通常我们都是分页公式,(pageIndex-1)* pageSize。Skip()、 Take()之类的方法。 一开始我就钻了个牛角尖,忘了他每页的【首屏数据是同步方式加载】的,这就计算了好几次公式都不对。OK。思路通了就开始看他们的源码。F12. 格式化、下断点。

      从ajax.php?module=getCarSalePost关键字搜索,很容易就找到上面这段代码。当然我最关心的就是这个方法的第二句代码:s=3*n-(3-i)。还有就是ajax的success事件中他们用到了history.replaceState({page:999},"","#"+s);  改变地址url而页面不刷新的。 HTML5 API新增的pushState()和replaceState()。n代表什么? i又是什么值呢?

n就是大分页的页码。第二页那n=2. i的变量在下面找到定义i=2也就是说他这里的计算是从小分页第二页开始的。 第一页也就是是首屏是同步的方式记载的。看到这里基本上这个三次加载和分页的思路就摸清楚了。     

      分析完这个我又整体看到了下他们的代码发现用到了define关键字。这就又开始了解下js模块化编程。

 

初探js模块化编程(CommonJs、AMD规范、CMD规范)

      初次接触js模块化编程是在学习node.js的过程,require、exports。众所周知node.js是采用了CommonJs。 

      在接触CommonJs、AMD、CMD前我们先了解下什么是模块化、模块化开发。

      模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题进行系统性的分解以之处理。模块化是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方式。可以想象一个巨大的系统代码,被整合优化分割成逻辑性很强的模块时,对于软件是一种何等意义的存在。对于软件行业来说:解耦软件系统的复杂性,使得不管多么大的系统,也可以将管理,开发,维护变得“有理可循”。

      还有一些对于模块化一些专业的定义为:模块化是软件系统的属性,这个系统被分解为一组高内聚,低耦合的模块。那么在理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可。
 
     首先,既然是模块化设计,那么作为一个模块化系统所必须的能力:
        1、定义封装的模块。
        2、定义新模块对其他模块的依赖。
        3、可对其他模块的引入支持。
 
 

AMD和CMD

       node.js中的模块化编程就是参照CommonJs实现的。在CommonJs中有一个全局方法require()。用于加载模块。 有了服务端模块以后,很自然大家就希望在浏览器端也有模块化编程。而且最好两者能够兼容,在服务端和客户端都能运行。

      CommonJs规范虽好但却不适合浏览器环境,因为require是同步方式运行,每引用一个lib就必须等待加载完成,也就是说加载时间过程的话浏览器就会假死,整个应用会停顿在哪里。因此,浏览器端的模块不能采用不同的方式记载,只能采用异步的方式记载,这就是AMD规范诞生的背景。

      AMD(Asynchronous Module Definition)意思就是异步模块定义。它采用异步的方式加载,模块的加载不影响后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

     目前采用AMD规范实现的Javascript库 require.js。

     require.js 主要解决两个问题:

        1、  多个js可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器

        2、  Js加载的时候浏览器会停止渲染页面,加载文件越多,页面失去响应时间越长。

      CMD(Common Module Definition),该规范明确了模块的基本书写格式和基本交互原则。在CMD规范中,一个文件就是一个模块,基本定义如下:

define(factory) 。define是一个全局函数用来定义模块,接受参数factory,factory可以是一个函数,也可以是一个对象或字符串。define({"foo":"bar"})。

 

    AMD和CMD又是什么区别呢?  AMD是提前执行,CMD是延迟执行。AMD速度快,会浪费资源,预先加载所有的依赖,直到使用的时候才执行。CMD只有真正使用才加载依赖,性能较差,直到使用时才定义依赖。

 

总结

      了解了CommonJs、AMD、CMD的基本概念后还需要对其代表的典型框架投入使用,如requirejs、seajs。 主键改造项目中纯function的现状和项目迭代因人为差异带来的成本。

 

参考资料

http://www.cnblogs.com/skylar/p/4065455.html
https://github.com/seajs/seajs/issues/277
https://www.douban.com/note/283566440/
http://blog.chinaunix.net/uid-26672038-id-4112229.html