zoukankan      html  css  js  c++  java
  • sencha touch 入门系列 (五)sencha touch运行及代码解析(上)

      由于最近项目比较忙,加之还要转战原生开发,所以很久没更新了,今天我们接着上一次的内容往下讲:

      首先我们打开index.html,这是我们整个程序的访问入口,也是整个项目的引入地:

      

     1 <!DOCTYPE HTML>
     2 <html manifest="" lang="en-US">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>MyFirst</title>
     6     <style type="text/css">
     7          /**
     8          * Example of an initial loading indicator.
     9          * It is recommended to keep this as minimal as possible to provide instant feedback
    10          * while other resources are still being loaded for the first time
    11          */
    12         html, body {
    13             height: 100%;
    14             background-color: #1985D0
    15         }
    16 
    17         #appLoadingIndicator {
    18             position: absolute;
    19             top: 50%;
    20             margin-top: -15px;
    21             text-align: center;
    22             width: 100%;
    23             height: 30px;
    24             -webkit-animation-name: appLoadingIndicator;
    25             -webkit-animation-duration: 0.5s;
    26             -webkit-animation-iteration-count: infinite;
    27             -webkit-animation-direction: linear;
    28         }
    29 
    30         #appLoadingIndicator > * {
    31             background-color: #FFFFFF;
    32             display: inline-block;
    33             height: 30px;
    34             -webkit-border-radius: 15px;
    35             margin: 0 5px;
    36             width: 30px;
    37             opacity: 0.8;
    38         }
    39 
    40         @-webkit-keyframes appLoadingIndicator{
    41             0% {
    42                 opacity: 0.8
    43             }
    44             50% {
    45                 opacity: 0
    46             }
    47             100% {
    48                 opacity: 0.8
    49             }
    50         }
    51     </style>
    52     <!-- The line below must be kept intact for Sencha Command to build your application -->
    53     <script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script>
    54 </head>
    55 <body>
    56     <div id="appLoadingIndicator">
    57         <div></div>
    58         <div></div>
    59         <div></div>
    60     </div>
    61 </body>
    62 </html>

    首先我们看第4行

      

    <meta charset="UTF-8">

      这个是设置浏览器的默认编码,创建项目的时候默认会创建为utf-8编码,当然你也可以设置成GBK这些,根据自己的实际需要来,正常情况下保持utf-8就可以了,若去掉这个标签,当页面出现中文的时候将会出现乱码

    12行的样式:

      

    html, body {
                height: 100%;
                background-color: #1985D0
     }

    这里是用来定义整个页面的高度为100%,以及它的背景色,开发时根据自己的实际需要修改

    17到50行的样式定义了一段css动画,通过id关联了body标签中的div:

      

    <div id="appLoadingIndicator">
            <div></div>
            <div></div>
            <div></div>
    </div>

    也就是我们项目打开时的那三个一直闪烁的小点,在项目的js文件载入完毕后,在app.js中通过Ext.fly('appLoadingIndicator').destroy()对其进行了销毁

    接下来最重要的就是53行引入的js了,这是整个项目js文件的入口:

    <script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script>

    你可以打开对应的js文件观察下代码,

    development.js的主要最用就是解析app.json文件(我们的资源文件的配置都写在里面,下面我们会给大家介绍下app.json文件的配置项)载入相关的资源文件,并对设备进行判断并设置一些css3媒体查询的内容

    关于css3的媒体查询,是个很强大的功能,在移动webapp,以及现在流行的响应式开发中都起着巨大的作用,大家可以网上自己百度或者google了解下,

    页面中meta标签中viewport的设置在android官方文档中也有讲解:http://developer.android.com/guide/webapps/best-practices.html

    下面我对代码做了简单的注释,因为这里的代码正常情况下我们不用去修改,所以大家简单了解下就可以,如果觉得看不懂代码或者想更好的学习js,强烈推荐《javascript高级编程》这本书,

    目前最新版本是第三版,看完对js的提升还是相当大的,读完之后可以再配合看看《javascript权威指南》,这本更适合作为工具书, 目前最新版本第6版

    /**
     * Sencha Blink - Development
     * @author Jacky Nguyen <jacky@sencha.com>
     */
    (function() {
        var head = document.head;
    
        function write(content) {
            document.write(content);
        }
    
        function addMeta(name, content) {
            var meta = document.createElement('meta');
    
            meta.setAttribute('name', name);
            meta.setAttribute('content', content);
            head.appendChild(meta);
        }
    
        //通过http请求读取app.json文件
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'app.json', false);
        xhr.send(null);
    
        //将读取的app.json文件的json内容解析为json对象
        var options = eval("(" + xhr.responseText + ")"),
            scripts = options.js || [],//如果存在js属性将对象中的js属性赋值给scripts变量,不存在则传空数组
            styleSheets = options.css || [],//同上,设置css属性
            i, ln, path, platform, theme, exclude;
    
        //判断app.json的json内容是否设置了platform属性,主要用来配置theme主题的
        if(options.platform && options.platforms && options.platforms[options.platform] && options.platforms[options.platform].js) {
            scripts = options.platforms[options.platform].js.concat(scripts);
        }
    
        //通过浏览器的userAgent来判断是否是ie10,如果是创建css3媒体查询设置
        if (navigator.userAgent.match(/IEMobile/10.0/)) {
            var msViewportStyle = document.createElement("style");
            msViewportStyle.appendChild(
                document.createTextNode(
                    "@media screen and (orientation: portrait) {" +
                        "@-ms-viewport { 320px !important;}" +
                    "}" +
                    "@media screen and (orientation: landscape) {" +
                        "@-ms-viewport { 560px !important;}" +
                    "}"
                )
            );
            document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
        }
    
        //设置页面的meta标签,控制页面的缩放以及宽高等
        addMeta('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
        addMeta('apple-mobile-web-app-capable', 'yes');
        addMeta('apple-touch-fullscreen', 'yes');
    
        if (!window.Ext) {
            window.Ext = {};
        }
        Ext.microloaded = true;
    
        //平台过滤对象,判断项目位于什么设备平台上
        var filterPlatform = window.Ext.filterPlatform = function(platform) {
            var profileMatch = false,
                ua = navigator.userAgent,
                j, jln;
    
            platform = [].concat(platform);
    
            function isPhone(ua) {
                var isMobile = /Mobile(/|s)/.test(ua);
    
                // Either:
                // - iOS but not iPad
                // - Android 2
                // - Android with "Mobile" in the UA
    
                return /(iPhone|iPod)/.test(ua) ||
                          (!/(Silk)/.test(ua) && (/(Android)/.test(ua) && (/(Android 2)/.test(ua) || isMobile))) ||
                          (/(BlackBerry|BB)/.test(ua) && isMobile) ||
                          /(Windows Phone)/.test(ua);
            }
    
            function isTablet(ua) {
                return !isPhone(ua) && (/iPad/.test(ua) || /Android|Silk/.test(ua) || /(RIM Tablet OS)/.test(ua) ||
                    (/MSIE 10/.test(ua) && /; Touch/.test(ua)));
            }
    
            // Check if the ?platform parameter is set in the URL
            var paramsString = window.location.search.substr(1),
                paramsArray = paramsString.split("&"),
                params = {},
                testPlatform, i;
    
            for (i = 0; i < paramsArray.length; i++) {
                var tmpArray = paramsArray[i].split("=");
                params[tmpArray[0]] = tmpArray[1];
            }
    
            testPlatform = params.platform;
            if (testPlatform) {
                return platform.indexOf(testPlatform) != -1;
            }
    
            //如果用户在app.json中配置了platform设置,判断当前平台进行匹配
            for (j = 0, jln = platform.length; j < jln; j++) {
                switch (platform[j]) {
                    case 'phone':
                        profileMatch = isPhone(ua);
                        break;
                    case 'tablet':
                        profileMatch = isTablet(ua);
                        break;
                    case 'desktop':
                        profileMatch = !isPhone(ua) && !isTablet(ua);
                        break;
                    case 'ios':
                        profileMatch = /(iPad|iPhone|iPod)/.test(ua);
                        break;
                    case 'android':
                        profileMatch = /(Android|Silk)/.test(ua);
                        break;
                    case 'blackberry':
                        profileMatch = /(BlackBerry|BB)/.test(ua);
                        break;
                    case 'safari':
                        profileMatch = /Safari/.test(ua) && !(/(BlackBerry|BB)/.test(ua));
                        break;
                    case 'chrome':
                        profileMatch = /Chrome/.test(ua);
                        break;
                    case 'ie10':
                        profileMatch = /MSIE 10/.test(ua);
                        break;
                    case 'windows':
                        profileMatch = /MSIE 10/.test(ua) || /Trident/.test(ua);
                        break;
                    case 'tizen':
                        profileMatch = /Tizen/.test(ua);
                        break;
                    case 'firefox':
                        profileMatch = /Firefox/.test(ua);
                }
                if (profileMatch) {
                    return true;
                }
            }
            return false;
        };
    
        //在页面中动态将app.json中配置的css文件引入
        for (i = 0,ln = styleSheets.length; i < ln; i++) {
            path = styleSheets[i];
    
            if (typeof path != 'string') {
                platform = path.platform;
                exclude = path.exclude;
                theme = path.theme;
                path = path.path;
            }
    
            if (platform) {
                if (!filterPlatform(platform) || filterPlatform(exclude)) {
                    continue;
                }
                Ext.theme = {
                    name: theme || 'Default'
                };
            }
    
            write('<link rel="stylesheet" href="'+path+'">');//输出到页面
        }
    
        //在页面中动态将app.json中配置的js文件引入
        for (i = 0,ln = scripts.length; i < ln; i++) {
            path = scripts[i];
    
            if (typeof path != 'string') {
                platform = path.platform;
                exclude = path.exclude;
                path = path.path;
            }
    
            if (platform) {
                if (!filterPlatform(platform) || filterPlatform(exclude)) {
                    continue;
                }
            }
    
            write('<script src="'+path+'"></'+'script>');//输出到页面
        }
    
    })();

    好玩developement.js,我们来看下它所解析的app.json文件,

    注意:正是因为developement.js里是通过http请求来获取app.json文件的,所以用sencha cmd创建的项目必须放到服务器环境下或者打包成安装程序才能运行,直接打开index.html是会报错,无法运行项目的

    app.json:

    {
        /**
         * 应用的命名空间,在项目中自定义项目文件时都要以这个命名空间开头,例如自定义一个名为MyTest的view,必须得MyFirst.view.MyTest,否则会找不到文件
         */
        "name": "MyFirst",
    
        /**
         * 项目的访问页面的地址
         */
        "indexHtmlPath": "index.html",
    
        /**
         * 项目开发环境下的绝对地址
         * 例如在你开发环境下的地址 "http://localhost/myapp/index.html".
         *
         * 这个属性一般不需要设置,除非你需要发布的时候引用服务端特定的资源文件,这时你可以设置对应的服务端地址
         */
        "url": null,
    
        /**
         * 项目中自定义的引用的js文件.
         * 每一个js文件都被定义为一个json属性对象:
         *      {
         *          "path": "path/to/script.js" // 相对于app.json文件的js路径
         *          "remote": true              // (选项)
         *                                      // - remote:该js文件是否是引用的远程文件,如果设置为true即远程文件,在用sencha cmd项目打包的时候这个
       *                     // - js文件就不会被打包压缩到app.js文件(在app.json文件中配置的资源文件在打包时所有的js文件都会被打包* *                      //   到app.js文件中压缩成一行)   
       *                      // - 中,其默认值为undefined,也就是被打包压缩过来 * "update": "delta" // (选项) * // - 如果没有指定这个选项,这个文件只会被载入一次 * // 同时缓存在localstorage(html5离线缓存)中直到它的值发生了改变 * // - "delta" 设置为改选项将会增量更新即只更新修改的部分,在2.2.1版本中发布production带离线缓存的版本   *                      //    时设置这个属性在js需要更新   
       *                      //   时更新后,项目会报错,新版本是否修复该问题未知 * // - "full" 完全更新整个js文件 * "x-bootstrap": true // (Optional) * // 标明文件跟开发模式的依赖关系 * // 这些文件将不会拷贝到生成目录中 * // 只会被development.js引用. * * }
    */ "js": [ { "path": "touch/sencha-touch.js", "x-bootstrap": true }, { "path": "bootstrap.js", "x-bootstrap": true }, { "path": "app.js", "bundle": true, /* 表示所有的js文件在打包生成时都合并到app.js文件中 */ "update": "delta" } ], /** * css文件的列表 * 每一项都是一个json对象 * { * "path": "path/to/item.css" // Path to file, if local file it must be relative to this app.json file * "remote": true // (Optional) * // - Defaults to undefined (falsey) to signal a local file which will be copied * // - Specify true if this file is a remote file which will not to be copied * "update": "delta" // (Optional) * // - If not specified, this file will only be loaded once, and * // cached inside localStorage until this value is changed to either one below * // - "delta" to enable over-the-air delta update for this file * // - "full" means full update will be made when this file changes * * } */ "css": [ { "path": "resources/css/app.css", "update": "delta" } ], /** * 设置html5离线缓存的缓存文件 */ "appCache": { /** * 缓存文件 */ "cache": [ "index.html" ], /** * 网络选择 */ "network": [ "*" ], /** * 回调项 */ "fallback": [] }, /** * 设置扩展的资源文件路径,这些文件也会在打包的时候一起被打包进资源文件 */ "resources": [ "resources/images", "resources/icons", "resources/startup" ], /** * File / directory name matchers to ignore when copying to the builds, must be valid regular expressions */ "ignore": [ ".svn$" ], /** * Directory path to store all previous production builds. Note that the content generated inside this directory * must be kept intact for proper generation of deltas between updates */ "archivePath": "archive", /** * List of package names to require for the cmd build process */ "requires": [ ], /** * Uniquely generated id for this application, used as prefix for localStorage keys. * Normally you should never change this value. */ "id": "23568a9e-e669-4786-b057-738279cffe3f" }

    developement.js解析完成后,项目就会载入app.js文件,从而进入我们整个项目了.

    这里顺便提及一下js文件中引入的sencha-touch.js, 这是sencha cmd创建项目时生成的引用,

    也是我们项目开发中推荐的引用,当你打开sencha的sdk文件夹时,你应该能看到下面4种js

    sencha-touch.js :

      sencha touch压缩后的核心代码库,里面只包括了sencha touch的sdk中的核心代码,当你需要其他功能得时候,需要通过requires(我们会在后面的教程中详细讲解)的方式来引用指定的js,在项目完成后,使用sencha cmd的打包压缩功能,只有requires的代码、核心代码以及用户自己写的项目代码会被压缩到app.js中,这样,就保证了项目文件的最小化。包括phonegap从3.0开始也采用了模块化的结构,需要的功能才引入,保证文件最小化

      

    sencha-touch-all.js:

      顾名思义,这个-all.js就是sencha touch压缩后的所有代码了,除非特殊情况,否则我们很少会使用这个文件。

    sencha-touch-all-debug.js :

      这个是包含了未压缩的sencha touch的所有代码的js文件,看到debug,很多有开发经验的同学应该知道这个文件是用来调试用的了:

    sencha-touch-debug.js:

      未压缩的核心代码库文件

    在sdk目录下的builds文件夹下,还有个

    sencha-touch-all-compat.js:

      这个js文件比较特殊,因为sencha touch从1.x版本到2.x版本的变化比较大,两个版本没法做到兼容,这个js就是为了让1.x版本升级到2.x版本来引用的,如果

    你手头的项目是1.x版本的,你想升级为2.x版本,你就需要在更新了sdk版本后引用该js文件来达到兼容升级的作用

    下一讲,我们将从app.js开始介绍整个项目的运行流程及mvc的处理方式

  • 相关阅读:
    HttpModule
    phpcms(1)
    ajax,json
    ajax 参数 小记
    PHP中文件操作基础:目录操作,文件操作
    PHP,获取文件夹下所有文件数量的方法。
    PHP中文件操作基础:文件路径基础
    js,jquery基础使用方法
    PHP基础知识测试题
    PHP中单例模式与工厂模式,
  • 原文地址:https://www.cnblogs.com/cjpx00008/p/3604602.html
Copyright © 2011-2022 走看看