require、backbone等重构手机图片查看器

本文是对之前的部分补充,也是对最近学习require、backbone的一次实例化的实践,希望对正在学习理解中的同学们有帮助

新手机图片查看器

网页部分

require引入是重点,指明了主函数所在文件路径

<!doctype html>
<html lang="zh-cn">
<head>
<title>webapp图片查看器</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
<script src="http://cdn.file1.goodid.com/static/js/require.min.js" data-main="/static/js/pic/main"></script>
</head>
<body>
<section class="index">
 <h1>手机网页图片查看器</h1>
 <figure class="download">
 <a>其它文件</a>
 <a url="http://static.bootcss.com/www/assets/img/opencdn.png">图片a</a>
 <a url="http://static.bootcss.com/www/assets/img/buttons.png">图片b</a>
 <a>其它文件</a>
 <a>其它文件</a>
 <a url="http://static.bootcss.com/www/assets/img/gruntjs.png">图片c</a>
 <a url="http://static.bootcss.com/www/assets/img/lesscss.png">图片d</a>
 <a>其它文件</a>
 </figure>
</section>
</body>
</html>

require.js加载完成后即加载main.js;样式部分就不占篇幅了,后面自己看完整网页 

模版引擎部分

第一个是对话框、第二个是当前位置、第三个是当前展示图片

<script id="dialog_tmpl" type="text/template">
<section></section>
<figure id="swipe"><ul></ul></figure>
<footer>
 <span id="l">左旋</span>
 <span id="r">右旋</span>
 <span id="pos" index="<%=index %>" length="<%=length %>"><%=index %>/<%=length %></span>
</footer>
</script>

<script id="pos_tmpl" type="text/template">
<span id="pos" index="<%=index %>" length="<%=length %>"><%=index %>/<%=length %></span>
</script>

<script id="item_tmpl" type="text/template">
<img src="<%=src %>" width="<%=width %>" height="<%=height %>" url="<%=url %>" />
</script>

3个模版需要写入HTML文件内 

程序开发部分

主函数main.js

require.config({
 paths : {
 jquery : 'http://cdn.file1.goodid.com/static/js/zepto.min',
 fastclick : 'http://cdn.file1.goodid.com/static/js/fastclick.min',
 underscore : 'http://cdn.file1.goodid.com/static/js/underscore.min',
 backbone : 'http://cdn.file1.goodid.com/static/js/backbone.min',
 swipe : 'http://cdn.file1.goodid.com/static/js/swipe.min'
 },
 shim : {
 jquery : {
 exports : '$'
 },
 fastclick : {
 deps : ['jquery']
 }
 }
});

require(['underscore', 'backbone', 'fastclick'], function (){
 FastClick.attach(document.body);
 require(['./view/global'], function(Global){
 var global = new Global;
 });
});

paths定义了各模块路径;shim中重新解析了jquery模块,fastclick(一款帮助提高触摸体验的微型插件)指明依赖模块jquery

require首先依次加载underscore、backbone、jquery、fastclick模块,然后再加载全局控制视图global模块并实例化 

全局控制视图global.js

define(['model/pic', 'collection/set', 'view/imager'], function (Pic, Set, Imager){
 var set = new Set;

 // 全局控制视图
 var global = Backbone.View.extend({
 el : 'body',
 data : $('.download [url]'),
 events : {
 'click .download [url]' : 'open'
 },
 open : function (model){
 var url = $(model.target).attr('url');
 var index = this.data.index($(model.target));
 var length = this.data.length;
 var total = new Pic.total({
 index : index + 1,
 length : length
 });
 var dialog = new Imager.dialog({
 model : total
 });
 $(this.el).prepend(dialog.render().el); // 绘制图片查看器

 this.collect();
 this.list();
 this.swipe(index);
 this.loading(url, index);
 },
 collect : function (){
 if(set.length > 0) return false;

 this.data.each(function(){
 var name = $(this).text();
 var url = $(this).attr('url');
 var item = new Pic.item({
 name : name,
 url : url
 });
 set.add(item); // 添加模型
 });
 },
 list : function (){
 var obj = $('#swipe ul');
 set.each(function(model){
 var list = new Imager.list({
 model : model
 });
 obj.append(list.render().el); // 绘制图片列表
 });
 },
 swipe : function (index){
 require(['swipe'], function(){
 var swipe = new Imager.swipe;
 swipe.render(index).el; // 绘制图片滑动特效
 });
 },
 loading : function (url, index){
 var item = new Pic.item({
 url : url
 });
 var loading = new Imager.loading({
 model : item,
 el : $('#swipe li').eq(index).find('img')
 });
 loading.render(); // 绘制图片加载
 }
 });

 return global;
});

依次加载它依赖的数据模型pic模块、数据集合set模块、渲染视图imager模块并实例化了一个集合模块

全局控制视图中我们定义了:绘制图片查看器的open方法、添加模型的collect方法、绘制图片列表的list方法、绘制图片滑动特效的swipe方法、绘制图片加载的loading方法

 渲染视图imager.js

define(['model/pic'], function (Pic){
 var imager = Object;

 // 图片查看器视图
 imager.dialog = Backbone.View.extend({
 initialize : function (){
 _.bindAll(this, 'render');
 },
 tagName : 'section',
 className : 'dialog',
 template : _.template($('#dialog_tmpl').html()),
 events : {
 'click #l, #r' : 'turn'
 },
 render : function (){
 $(this.el).html(this.template(this.model.toJSON()));
 return this;
 },
 turn : function(model){
 var index = parseInt($('#pos').attr('index')) - 1;
 var obj = $('#swipe li').eq(index).find('img');
 var deg = parseInt(obj.attr('deg') ? obj.attr('deg') : 0);
 var type = model.target.id;
 if(type && type == 'l') deg -= 90;
 else if(type && type == 'r') deg += 90;
 if(deg > 360) deg -= 360;
 else if(deg < -360) deg += 360;
 obj.css({'-webkit-transform':'rotate(' + deg + 'deg)'}).attr({'deg':deg});
 }
 });

 // 图片列表视图
 imager.list = Backbone.View.extend({
 initialize : function (){
 _.bindAll(this, 'render');
 },
 tagName : 'li',
 template : _.template($('#item_tmpl').html()),
 events : {
 'click img' : 'close'
 },
 render : function (){
 $(this.el).html(this.template(this.model.toJSON()));
 return this;
 },
 close : function (){
 $('.dialog').remove();
 }
 });

 // 图片滑动定位视图
 imager.fix = Backbone.View.extend({
 initialize : function (){
 _.bindAll(this, 'render');
 },
 el : '#pos',
 template : _.template($('#pos_tmpl').html()),
 render : function (){
 $(this.el).replaceWith(this.template(this.model.toJSON()));
 $('#swipe [deg]').removeAttr('deg').removeAttr('style');
 return this;
 }
 });

 // 图片加载视图
 imager.loading = Backbone.View.extend({
 initialize : function (){
 _.bindAll(this, 'render');
 },
 template : _.template('<img src="<%=url %>" />'),
 render : function (){
 var obj = $(this.el);
 var html = this.template(this.model.toJSON());
 var img = new Image();
 img.src = this.model.attributes.url;
 img.onload = function(){
 obj.replaceWith(html);
 };
 return this;
 }
 });

 // 图片滑动特效视图
 imager.swipe = Backbone.View.extend({
 initialize : function (){
 _.bindAll(this, 'render');
 },
 render : function (index){
 var obj = document.getElementById('swipe');
 window.mySwipe = Swipe(obj, {
 startSlide : index,
 continuous : false,
 disableScroll : true,
 callback : function(index, element){
 var length = $('#pos').attr('length');
 var total = new Pic.total({
 index : index + 1,
 length : length
 });
 var fix = new imager.fix({
 model : total
 });
 fix.render(); // 绘制图片滑动定位

 var url = $(element).find('img').attr('url');
 if(!url || url.length == 0) return false;

 var item = new Pic.item({
 url : url
 });
 var loading = new imager.loading({
 model : item,
 el : $(element).find('img')
 });
 loading.render(); // 绘制图片加载
 }
 });
 return this;
 }
 });

 return imager;
});

数据模型pic.js

define(function (){
 var pic = Object;

 // 图片数据统计模型
 pic.total = Backbone.Model.extend({
 defaults : {
 index : 1,
 length : 1
 }
 });

 // 图片数据模型
 pic.item = Backbone.Model.extend({
 defaults : {
 name : '图片加载中...',
 src : 'http://cdn.file1.goodid.com/static/images/loading.gif',
 url : '',
 width : 40,
 height : 40
 }
 });

 return pic;
});

数据集合set.js

define(['model/pic'], function (Pic){
 // 图片数据集合
 var set = Backbone.Collection.extend({
 model : Pic.item
 });

 return set;
});

模块定义让程序更加清晰了,模块加载让文件加载执行在我们的掌控之中;MVC模式(C还没用上)让数据逻辑层等分离更加顺手减少了代码混乱。

作者:大白兔

%s 个评论

要回复文章请先登录注册