• 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还没用上)让数据逻辑层等分离更加顺手减少了代码混乱
  • 相关阅读:
    day37 多路复用IO模型之select select,poll,epoll 异步IO 数据库基本概念 配置文件管理
    day36 协程介绍/yield实现协程/补充/gevent模块/网络IO模型介绍/阻塞IO模型/非阻塞IO模型
    day35 GIL介绍 cpython解释器的垃圾回收机制 GIL与自定义互斥锁 多进程vs多线程 线程queue 进程池与线程池
    day34 线程介绍/开启线程的两种方式/进程vs线程/线程对象其他相关属性或方法/互斥锁/死锁现象与递归锁/信号量
    day33 守护进程、互斥锁、进程间通信、生产者消费者模型part1、生产者消费者模型part2、生产者消费者模型part3
    day 32 进程理论/开启子进程的两种方式/僵尸进程与孤儿进程/进程间内存空间隔离/join操作/进程对象其他相关属性或方法
    day31 基于udp协议套接字通信 udp协议通信循环原理分析 udp协议没有粘包问题/基于socketserver模块实现并发的套接字(tcp) 基于socketserver模块实现并发的套接字(udp) 进程的简单介绍 操作系统的功能介绍 操作系统的发展史
    day30 模拟ssh远程执行命令/解决粘包执行问题/粘包终极解决方案/tcp的优化算法以及粘包问题分析
    Unity3D游戏开发之MatchTarget实现角色攀爬效果
    javase学习第九天(抽象类与接口)
  • 原文地址:https://www.cnblogs.com/johnl/p/4277538.html
Copyright © 2020-2023  润新知