基础的网页基本上之前讲的东西便足够了,但是网页基本上是离不开后台的数据的,当后台需要传一组数据过来让网页加载的时候,我们该怎么办?

首先,下面是rank页面,页面中显示一些程序的排名——

 1     <section style="display:none" id="rank" style="display:block" class="rank">
 2         <div class="rule_desc">活动规则</div>
 3         <div class="rank_head">
 4             <div class="rank_logo"></div>
 5             <div class="rank_desc">
 6                 全民助力夺榜单<br>免费上班专线抢先坐
 7             </div>
 8         </div>
 9         <div class="rank_list">
10             <ul class="list_item js-ranklist">
11                 
12             </ul>
13         </div>
14         <div class="submit_button">
15             
16         </div>
17     </section>

前台页面这么多就够了,而且我们主要是需要rank.list这个div中显示后台数据。首先,将各式各样的css添加上去;

  1 .rank .rank_head {
  2     
  3 }
  4 .rank_name {
  5     font-size: 16px;
  6 }
  7 .rank .rank_head .rank_logo{
  8     background: url(../img/rankimg/titlelogo.png);
  9     background-size: 100% 100%;
 10     width: 14.784rem;
 11     height: 6.869333rem;
 12     position: relative;
 13     left: 50%;
 14     -webkit-transform: translate(-50%);
 15     transform: translate(-50%);
 16 }
 17 
 18 .rank .rank_desc {
 19     margin-top: -2.1rem;
 20     text-align: center;
 21     font-weight: bold;
 22 }
 23 .rule_desc {
 24     position: absolute;
 25     right: 0;
 26     top: 0;
 27     margin-top: .5rem;
 28     margin-right: .8rem;
 29     font-size: 18px;
 30     font-weight: bold;
 31 }
 32 .rank .rank_list {
 33     width: 13.533333rem;
 34     max-height: 15.266667rem;
 35     margin: 0.8rem auto;
 36     background: white;
 37     overflow: hidden;
 38     position: relative;
 39 }
 40 
 41 .rank .list_item {
 42     margin: 0 0.4rem;
 43 }
 44 .inl {
 45     display: inline-block;
 46 }
 47 .rank .list_item li{
 48     position: relative;
 49     height: 2.2rem;
 50     line-height: 2.2rem;
 51     border-bottom: 1px solid rgba(102,102,102,.14);
 52 }
 53 .rank .list_item  {
 54     background: white;
 55     width: 13.533333rem;
 56     /* max-height: 15.266667rem; */
 57     /* overflow-y: scroll; */
 58 }
 59 .rank .left_pane {
 60     background: white;
 61     z-index: 8;
 62     position: relative;
 63     padding-left: .7rem;
 64     left: -0.7rem;
 65 }
 66 .rank .right_pane {
 67        padding-top: 0.3rem;
 68     width: 10rem;
 69     background: white;
 70     z-index: 7;
 71     transition: left 2s linear;
 72     -webkit-transition: left 2s linear;
 73     height: 1.5rem;
 74     top: 0.35rem;
 75     left: 0;
 76     margin-left: -2.8rem;
 77     display: inline-block;
 78     position: relative;
 79     vertical-align: top;
 80 }
 81 .right_pane .bus_info {
 82     background: url(../img/rankimg/buslogo.png);
 83     background-size: 100% 100%;
 84     width: 1.877333rem;
 85     height: 0.768rem;
 86     line-height: 0.768rem;
 87     text-align: center;
 88     font-size: 13px;
 89     width: 1.877333rem;
 90     overflow: hidden;
 91     color: white;
 92 }
 93 .rank_number {
 94     background: url(../img/rankimg/blackIcon.png);
 95     background-size: 100% 100%;
 96     width: 0.917333rem;
 97     height: 0.874667rem;
 98     line-height: 0.874667rem;
 99     color: white;
100     font-size: 15px;
101     text-align: center;
102 }
103 .rank .barline {
104     background: url(../img/rankimg/bar.png);
105     background-size: 100% 100%;
106     width: 8.128rem;
107     height: 0.64rem;
108     position: absolute;
109     top: 0.8rem;
110     left: 2.5rem;
111     z-index: 4;
112 }
113 .rank .citybar {
114     background: url(../img/rankimg/city.png);
115     background-size: 100% 100%;
116     width: 6.101333rem;
117     height: 1.536rem;
118     position: absolute;
119     top: 0.19rem;
120     left: 5.5rem;
121     z-index: 6;
122     animation-delay: 1.5s;
123 }
124 
125 @-webkit-keyframes runcity {
126       from {
127         transform: translateX(9rem);
128         -webkit-transform: translateX(9rem);
129       }
130       100% {
131         transform: translateX(-5rem);
132         -webkit-transform: translateX(-5rem);
133       }
134 }
135 @keyframes runcity {
136       from {
137         transform: translateX(9rem);
138         -webkit-transform: translateX(9rem);
139       }
140       100% {
141         transform: translateX(-10rem);
142         -webkit-transform: translateX(-10rem);
143       }
144 }

插完之后,我们开始写js代码。

我们的目标是在rank.list这个div中,用列表的方式,输出城市的信息,包括名字和数量。

那么,首先我们需要数据源,这里模拟一个json数据过来:data.json

{
    "北京": 1200,
    "杭州": 800,
    "上州": 500,
    "哈尔滨": 500,
    "圳州": 220,
    "州州": 210,
    "海州": 150,
    "哈州": 120,
    "深州": 110,
    "鄂尔多斯": 80,
    "海的州": 150,
    "哈额州": 120,
    "深州我": 110,
    "鄂尔多的斯": 80,
    "北京市博士":20
}

,然后,接着书写rank.js模块——

 1 window.rankModule = Object.create(baseModule);
 2 //每个对象互相独立---》简称继承
 3 (function(){
 4     var selfModule = {
 5         el: $('#rank'),
 6         name: '我是排名页',
 7         listel: $(".js-ranklist"),
 8         init: function(){
 9             this.getData();
10             console.log('我在getData后面');
11             console.log('我是重载的init方法');             
12         },
13         enter: function(){
14             this.el.show();
15             $(EventCenter).trigger('returnTop');     
16         },
17         renderContent: function(obj){
18             str = "";
19             var targetNum = null;
20             var count = 0;
21             for(var key in obj) {
22                 if(count === 0) {
23                     targetNum = obj[key];
24                 }
25                 var LEFT_OFFSET_REM = 9.5;
26                 var dotted_num = LEFT_OFFSET_REM/targetNum;
27                 var left = dotted_num * obj[key];
28                 if(left < 2.8) {
29                     left = 2.8 + left;
30                 }
31                 count++;
32                 str += '<li>' +
33                         '    <div class="left_pane inl">' +
34                         '        <div class="rank_number inl">' + count + '</div>' +
35                         '        <div class="rank_name inl">' + key + '</div>' +
36                         '    </div>' +
37                         '    <div data-left="' + left + '" class="right_pane inl">' +
38                         '        <div class="bus_info">' +
39                         '            ' + obj[key] + '人' +
40                         '        </div>' +
41                         '    </div>' +
42                         '    <div class="barline"></div>' +
43                         '    <div class="citybar" style="animation:runcity '+ (3 - obj[key]/targetNum ) +'s infinite linear both 1.5s;-webkit-animation:runcity '+ (3 - obj[key]/targetNum ) +'s infinite linear both 1.5s;"></div>' +
44                         '</li>';
45             }
46             this.listel.html(str);
47             setTimeout(function(){
48                 $(".right_pane").each(function(index, val){
49                    val.style.left = val.dataset.left + 'rem';
50                 });         
51             }, 1000)
52             //IScroll 就是iscroll.js暴露出的全局变量
53         },
54         bindEvent: function(){
55             
56         },
57         getData: function(){
58             var me = this;
59             $.ajax({
60                 url: "js/data.json",
61                 type: 'get',
62                 success:function(res){
63                     console.log('异步代码');
64                     if(typeof res === "string") {
65                         res = JSON.parse(res)
66                     }else {
67                         res = res;
68                     }
69                     me.renderContent(res);
70                     $(EventCenter).trigger('iscroll_load');
71                     console.log(res);
72                 },
73                 error: function(res){
74                     console.log(res);     
75                 }
76             })
77         }
78     }
79     $.extend(rankModule,selfModule);
80 })();

第一行当然是模块声明,暴露一个rankModule模块,获得公共模块的各个属性。

接下来是闭包,然后是selfModel对象。和首页对象不同,这个里面多了一写东西:

listel:list el这个和上面的el都是用来获得元素用的

init:这个函数是rank的初始化函数,里面只有一个方法:this.getData,这个方法是进行ajax操作用的,下面会讲到。

 

enter:注意到这个函数当中,除了有个show()方法之外,还多了一个$(EventCenter).trigger('returnTop'); 

这个是触发器,为了防止代码污染安全获得其他模块内容的类似于中介的模块,意思是,调用这个EventCenter(一个接口),触发'returnTop事件。

一般来说很少有一个模块直接调用另一个模块的内容的,因为将另一个模块引进来的话,那个模块所带的变量函数也会进入这个模块,一旦两个模块重名了,那么各种恶心的重写就会导致这个模块可能就用不了了。所以模块之间最好不要直接调用,于是就建造一个新的模块充当中介,安全方便。原理接下来讲解。

 

 

renderContent:独有的方法

 1 str = "";
 2             var targetNum = null;
 3             var count = 0;
 4             for(var key in obj) {
 5                 if(count === 0) {
 6                     targetNum = obj[key];
 7                 }
 8                 var LEFT_OFFSET_REM = 9.5;
 9                 var dotted_num = LEFT_OFFSET_REM/targetNum;
10                 var left = dotted_num * obj[key];
11                 if(left < 2.8) {
12                     left = 2.8 + left;
13                 }
14                 count++;
15                 str += '<li>' +
16                         '    <div class="left_pane inl">' +
17                         '        <div class="rank_number inl">' + count + '</div>' +
18                         '        <div class="rank_name inl">' + key + '</div>' +
19                         '    </div>' +
20                         '    <div data-left="' + left + '" class="right_pane inl">' +
21                         '        <div class="bus_info">' +
22                         '            ' + obj[key] + '人' +
23                         '        </div>' +
24                         '    </div>' +
25                         '    <div class="barline"></div>' +
26                         '    <div class="citybar" style="animation:runcity '+ (3 - obj[key]/targetNum ) +'s infinite linear both 1.5s;-webkit-animation:runcity '+ (3 - obj[key]/targetNum ) +'s infinite linear both 1.5s;"></div>' +
27                         '</li>';
28             }
29             this.listel.html(str);

首先解释一个实现效果,我们想要小车在刷新的时候从左到右运动,同时出现城市北京和喷气背景,这个背景长度会随着小车的前进而增加,到达特定的值一起停止。这个值是动态的,会根据返回的城市的值的数字到达不同的位置:

 

 

 

 

 

 

这一部分中,第一个创建一个空字符串str,用来保存一条li中的所有数据,现在的值是空。

第二句,创建一个targetNum,获取城市后面的数字数据,现在也是空。

第三句,设置计数器。

当计数器为0的时候,将data.json中第一个对象的值付给它。

设定li中,图片区总长度,这里是9.5rem

left:设定偏移量,以第一个城市的数量为基准,这个数字(1200)对应的长度是9.5rem,之后依次根据城市后面的数字计算并设定不同的偏移量数值。

计数器+1

将需要的html代码写好,并保存到str中

 

this.listel.html(str);将这一次的循环写在ul中。str中内容就是第一个li了,接下来会一直循环,直到json值全部输出为止。

 

然后是设置定时器,因为城市背景需要在小车跑完之后才出现,并且一直跑下去,而这个操作是【异步的】,所以只能放在这里而不能放在模块中。

setTimeout(function(){
                $(".right_pane").each(function(index, val){
                   val.style.left = val.dataset.left + 'rem';
                });         
            }, 1000)

 

 

之后是getdata方法,这个是通过ajax获得json数据内容。整个模块的启动过程是init中启动ajax,ajax获得数据后启动私有方法,私有方法进行li的加载。

 

最后进行两个模块的合并就完了。

然而事情没有结束,还有善后工作。刚刚我们说了我们需要第三方模块充当中介,于是这个模块就顺手放到init.js文件中了——

 1 window.EventCenter = {};  //-->全局事件中心
 2 window.myScroll = null;
 3 $(EventCenter).bind('iscroll_load', function(){
 4     myScroll = new IScroll('.rank_list', {
 5        scrollbars: true,
 6        bounce:true
 7     });
 8 });
 9 
10 $(EventCenter).bind('returnTop', function(){
11     if (myScroll) {
12         myScroll.scrollTo(0, 0);
13     }
14 });
15 
16 $(EventCenter).bind('loading', function(){
17     Loading.loading();
18 });
19 
20 $(EventCenter).bind('loaded', function(){
21     Loading.loaded();
22 });

基本上所有的事件都会写在这里,然后供各个函数调用,安全无污染。

通过给这个对象模块绑定大量的监视器来达到目的,上面就绑定了四个事件了,需要的话就继续写呗。