分享

单页WEB应用(一),结构和布局

 quasiceo 2017-09-24
原创 2017年02月10日 18:10:41

单页WEB应用(一),结构和布局

前两天买了两本书,一本《基于MVC的Javascript Web富应用开发》这本拿到手第二天大概的翻了一遍,没怎么深入去看,主要前面讲的基本的一些东西,后面的有些还没太看懂,所以大概的过了一遍;目前主要看的是这第二本《单页Web应用》,这个看到了第三章 Shell开发,看到这里代码也走了一遍,今天算是纠结在 uriAnchor 上纠结了一整天,最后才发现原来只是一个属性值的问题,痛苦ing……


本来不太想写这系列的博客记录的,但是由于今天的纠结,还是决定把这本书的读书笔记,写下来,每个环节给记录下,也方便自己理请思路,和研究其中相关的技术点和所用到的框架什么之类的,也方便以后再看第二遍的时候回顾下自己的思路和理解。

第一章和第二章主要内容大概就是创建项目文件结构,和一些基本文档结构定义和编码,因此放这一起记录。

单页应用文件结构定义

现在大家都在讲究模块化了,虽然这里目前还没用到这些,但是思想还是不能落下的,还是要划分下文件结构。

由于是单页应用,主页面也就只有一个,本书思想大概是在单个页面文件中定义出简单的整体结构,然后通过功能划分定义每个模块,最后通过组装到一起形成整个应用。

  • 文档结构

    都是简单的目录划分,就没必要一个个解释了,下面的 shell 其实就是整个文档结构的核心部分,算是容器吧(刚拿到这本书,看目录时候还以为是那种命令行的shell呢,要写个 shell 吓出身冷汗Σ( ° △ °|||)︴)

    
    结构中,css, js的文件名称都一一对应相应的页面来命名,比如:shell模块的样式,就用 spa.shell.css 等
    
    ---+ css
        ---- spa.css            // 对应主页面的样式
        ---- spa.shell.css      // shell 模块的样式
    ---+ js
        ---+ jq             // 由于该书的应用是基于 jQuery 实现的所以
            ---- jquery-1.9.1.js
    
            // 这个是个 URI 管理插件,是模拟浏览器后退前进功能的关键,后面会单独研究这个东西,被坑了一天(笨啊~~)
            ---- jquery.uriAnchor-1.3.3.js  
        ---- spa.js
        ---- spa.shell.js
    ---- spa.html   // 这个是单应用主页面
    ---- layout.html // 这个有点像是临时用的,给模块事先测试布局的
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

布局和样式编码

页面布局

结构定义创建好了,接下来就是将整体的布局和样式编码弄起来了,至少能看着像个样子,这里简单的绘制了个布局图

单页应用整体布局图

单页应用布局图

上图中,文档主体在:spa.html,其他部分其实都在 layout.html 中实现布局测试,然后生成 html 代码字符串,形成shell模块,通过initModule 添加到文档主体的容器中。

  • 主页面:spa.html包含单页应用整体架构容器

    这个页面代码量不多,目前来说,后面应该也不会太多,毕竟使用了模块概念,这样也避免了单页代码量太大的不良后续。

    // spa.html
    // spa.test.js 是自己加的一个测试模块文件
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>SPA</title>
    
        <link rel="stylesheet" href="css/spa.css">
        <link rel="stylesheet" href="css/spa.shell.css">
    
        <!-- 第三方库 -->
        <script src="js/jq/jquery-1.9.1.js"></script>
        <script src="js/jq/jquery.uriAnchor-1.3.3.js"></script>
    
        <!-- 测试代码 -->
        <script src="js/spa.test.js"></script>
    
        <script src="js/spa.js"></script>
        <script src="js/spa.shell.js"></script>
    
        <script>
    
            // 这里使用 jQuery 的加载接口,spa 的模块初始化来加载 shell 模块
            $(function () {
                spa.initModule( $('#spa') );
            });
        </script>
    </head>
    <body>
        <div id="spa"></div>    
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • shelllayout.html 页面

    想了下还是用 ‘某’ 之 ‘layout.html’ 页面为标题妥当些,主体文档页面完成了,接下来就是整个文档的核心架构部分了,也就是 shell模块

    该模块包含的页面元素,这里不得不说下,命名方式问题,作者的这种方式命名值得推荐的,毕竟页面的元素很多,能够根据具体模块名来连接命名,将更加方便以后的阅读和维护,更由于长期从事维护工作,看过的代码风格太多太多,看到下面这种风格还是比较耳目一新,很爽的(当然,太长了是不是有点~~~)。

    // layout.html ->> shell
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>HTML Layout</title>
        <link rel="stylesheet" href="css/spa.css">
        <link rel="stylesheet" href="css/layout.css">
    </head>
    <body>
        <div id="spa">
            <div class="spa-shell-head">
                <div class="spa-shell-head-logo"></div>
                <div class="spa-shell-head-acct"></div>
                <div class="spa-shell-head-search"></div>
            </div>
            <div class="spa-shell-main">
                <div class="spa-shell-main-nav"></div>
                <div class="spa-shell-main-content"></div>
            </div>
            <div class="spa-shell-foot"></div>
            <div class="spa-shell-chat"></div>
            <div class="spa-shell-modal"></div>
        </div>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    上面的代码结构,和上图的结构中元素一一对应

    1. spa:大容器;
    2. spa-shell-head:对应头部,其中包含 *-logo, *-acct, *-search 元素;
    3. spa-shell-content: 内容部分就两块,导航nav和具体内容content,这里有个地方需要记录下,就是内容块的扩张方式,通过给父元素添加样式来设置导航的宽度和内容的left来实现导航隐藏和显示;
    4. spa-shell-foot:底部,spa-shell-chat:聊天窗口,spa-shell-modal:漂浮的窗口。

页面样式

两个页面样式都是简单的样式定义,shell 布局都是通过决定定位实现,这里记录下内容块扩展样式

// 通过下面样式定义,然后在父元素上添加和移除 'spa-x-closed' 样式就可实现导航隐藏显示和内容区扩展和收缩
// 还是经验不足脑子抽,没想到过这种方式 

.spa-shell-main {
    top     : 40px;
    left    : 0;
    bottom  : 40px;
    right   : 0;
}

.spa-shell-main-content,
.spa-shell-main-nav {
    top     : 0;
    bottom  : 0;
}

.spa-shell-main-nav {
    width   : 250px;
    background  : #eee; 
}

.spa-x-closed .spa-shell-main-nav {
    width   : 0;
}

.spa-shell-main-content {
    left    : 250px;
    right   : 0;
    background  : #ddd; 
}

.spa-x-closed .spa-shell-main-content {
    left    : 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

测试代码文件:spa.test.js

/**
 * 测试代码文件
 * @authors zc li (ccc_simon@163.com)
 * @date    2017-02-09 16:53:58
 * @version $Id$
 */

function isObject( arg ) {
    return Object.prototype.toString.call( arg ) === '[object Object]';
}

function spa_debug( arg, name ) {

    // 对象输出方式
    if ( isObject( arg ) && name  ) {

        console.log( name + '------------>' );
        console.log( arg );
        console.log( '<------------' + name );

        return;
    }

    console.log( arg );
}


var TEST = (function () {

    var
        // 测试开关
        switcher = false,

        elements = {
            chat: $('spa-shell-chat')
        },

        // 滑块
        showChatSlider, hideChatSlider,

        // 取消测试代码
        closeTest, openTest, voidFn;

    showChatSlider = function ( fn ) {
        setTimeout(function () { fn && fn( true ); }, 3000);            
    };

    hideChatSlider = function ( fn ) {
        setTimeout( function () { fn && fn( false ); }, 8000 );
    };

    voidFn = function () {

        spa_debug( 'I am void function, nothing to do......' ); 
    };

    // 增加 need 参数,可以在总开关 switcher 关闭的情况下,启用单个测试用例函数
    function getFn( fn, need ) {

        return need ? fn : (switcher ? fn : voidFn);
    }

    return {
        showChatSlider: getFn( showChatSlider ),
        hideChatSlider: getFn( hideChatSlider )
    };

}());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

总结

上面就是简单的页面结构,布局和样式的一些记录,这中间并没什么难点,和纠结点地方,也快下班了,控制逻辑部分就留到下篇再说吧。

一写就停不下来,忍不住啰嗦啰嗦 ~~~~~~~~~~!!!

新年上班第一周问题不多,偶尔能有一两个都OK了,也都是顺手KO掉。最近也在考虑是否该换个环境了,才刚入门呢,就一直做着维护对自己的发展毕竟不是很有益,前端更新又如此之快,不赶紧上手实践更多的知识,自己都不敢说是做前端的(事实上现在也都不敢跟别人说是前端(工程师),囧囧囧囧囧囧囧囧囧囧

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多