一个完整的移动端项目的构建步骤——框架搭构6
Posted 起个好名字
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个完整的移动端项目的构建步骤——框架搭构6相关的知识,希望对你有一定的参考价值。
基础的网页基本上之前讲的东西便足够了,但是网页基本上是离不开后台的数据的,当后台需要传一组数据过来让网页加载的时候,我们该怎么办?
首先,下面是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 });
基本上所有的事件都会写在这里,然后供各个函数调用,安全无污染。
通过给这个对象模块绑定大量的监视器来达到目的,上面就绑定了四个事件了,需要的话就继续写呗。
以上是关于一个完整的移动端项目的构建步骤——框架搭构6的主要内容,如果未能解决你的问题,请参考以下文章