├── .bowerrc ├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── config.xml ├── gulpfile.js ├── hooks ├── README.md └── after_prepare │ └── 010_add_platform_class.js ├── package.json ├── resources ├── README.md ├── android │ ├── icon │ │ ├── drawable-hdpi-icon.png │ │ ├── drawable-ldpi-icon.png │ │ ├── drawable-mdpi-icon.png │ │ ├── drawable-xhdpi-icon.png │ │ ├── drawable-xxhdpi-icon.png │ │ └── drawable-xxxhdpi-icon.png │ └── splash │ │ ├── drawable-land-hdpi-screen.png │ │ ├── drawable-land-ldpi-screen.png │ │ ├── drawable-land-mdpi-screen.png │ │ ├── drawable-land-xhdpi-screen.png │ │ ├── drawable-land-xxhdpi-screen.png │ │ ├── drawable-land-xxxhdpi-screen.png │ │ ├── drawable-port-hdpi-screen.png │ │ ├── drawable-port-ldpi-screen.png │ │ ├── drawable-port-mdpi-screen.png │ │ ├── drawable-port-xhdpi-screen.png │ │ ├── drawable-port-xxhdpi-screen.png │ │ └── drawable-port-xxxhdpi-screen.png ├── icon.android.png ├── icon.ios.png ├── icon.png ├── ios │ ├── icon │ │ ├── icon-1024.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-60.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ ├── icon-83.5@2x.png │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ ├── icon-small@3x.png │ │ ├── icon.png │ │ └── icon@2x.png │ └── splash │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape@~ipadpro.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Portrait@~ipadpro.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default@2x~iphone.png │ │ ├── Default@2x~universal~anyany.png │ │ └── Default~iphone.png └── splash.png ├── screenshot ├── audio.gif ├── cate.gif ├── pdf.gif ├── scaleBanners.gif └── video.gif ├── src ├── components │ └── directives │ │ ├── html │ │ ├── mp3.html │ │ └── video.html │ │ └── js │ │ ├── carousel.js │ │ ├── mp3.js │ │ └── video.js ├── css │ ├── .DS_Store │ ├── category.css │ ├── samples.carousel.css │ ├── samples.mp3.css │ ├── samples.pdf.css │ ├── samples.video.css │ └── style.css ├── data │ ├── bio-list.json │ ├── category.json │ ├── com-list.json │ ├── eco-list.json │ ├── latest.json │ └── mag-list.json ├── images │ ├── adam.jpg │ ├── ben.png │ ├── bg-book.png │ ├── carousel │ │ ├── biol01.jpg │ │ ├── biol02.jpg │ │ ├── biol03.jpg │ │ ├── biol04.jpg │ │ ├── biol05.jpg │ │ ├── comp01.jpg │ │ ├── comp02.jpg │ │ ├── comp03.jpg │ │ ├── comp04.jpg │ │ ├── comp05.jpg │ │ ├── econ01.jpg │ │ ├── econ02.jpg │ │ ├── econ03.jpg │ │ ├── econ04.jpg │ │ ├── econ05.jpg │ │ ├── latest01.jpg │ │ ├── latest02.jpg │ │ ├── latest03.jpg │ │ ├── latest04.jpg │ │ └── latest05.jpg │ ├── icon-mp3.png │ ├── ionic.png │ ├── max.png │ ├── mike.png │ ├── perry.png │ ├── play-btn.png │ ├── post-bg.gif │ └── transparent.gif ├── index.html ├── js │ ├── app.js │ ├── app.templates.js │ ├── config.js │ ├── directives.js │ ├── global.js │ ├── mobile-move.js │ └── utils.js ├── media │ └── audio │ │ └── music.mp3 └── pages │ ├── account │ ├── account.controller.js │ ├── account.html │ └── account.route.js │ ├── category │ ├── category.controller.js │ ├── category.html │ └── category.route.js │ ├── chatDetail │ ├── chatDetail.controller.js │ ├── chatDetail.html │ └── chatDetail.route.js │ ├── dash │ ├── dash.controller.js │ ├── dash.html │ └── dash.route.js │ ├── samples │ ├── carousel │ │ ├── carousel.controller.js │ │ ├── carousel.directive.js │ │ ├── carousel.html │ │ └── carousel.route.js │ ├── mp3 │ │ ├── mp3.controller.js │ │ ├── mp3.html │ │ └── mp3.route.js │ ├── pdf │ │ ├── pdf.controller.js │ │ ├── pdf.html │ │ └── pdf.route.js │ └── video │ │ ├── video.controller.js │ │ ├── video.html │ │ └── video.route.js │ └── tab │ ├── tab.controller.js │ ├── tab.html │ └── tab.route.js ├── www ├── app │ ├── app.1517145267382.min.css │ ├── app.1517145267382.min.js │ ├── app.templates.1517145267382.min.js │ ├── vendor.1517145267382.min.css │ └── vendor.1517145267382.min.js ├── assets │ ├── fonts │ │ ├── ionicons.eot │ │ ├── ionicons.scss │ │ ├── ionicons.svg │ │ ├── ionicons.ttf │ │ ├── ionicons.woff │ │ ├── ionicons.woff2 │ │ ├── noto-sans-bold.ttf │ │ ├── noto-sans-bold.woff │ │ ├── noto-sans-regular.ttf │ │ ├── noto-sans-regular.woff │ │ ├── noto-sans.scss │ │ ├── roboto-bold.ttf │ │ ├── roboto-bold.woff │ │ ├── roboto-bold.woff2 │ │ ├── roboto-light.ttf │ │ ├── roboto-light.woff │ │ ├── roboto-light.woff2 │ │ ├── roboto-medium.ttf │ │ ├── roboto-medium.woff │ │ ├── roboto-medium.woff2 │ │ ├── roboto-regular.ttf │ │ ├── roboto-regular.woff │ │ ├── roboto-regular.woff2 │ │ └── roboto.scss │ ├── icon │ │ └── favicon.ico │ └── imgs │ │ └── logo.png ├── audio │ └── music.mp3 ├── build │ ├── main.css │ ├── main.css.map │ ├── main.js │ ├── main.js.map │ ├── polyfills.js │ ├── sw-toolbox.js │ ├── vendor.js │ └── vendor.js.map ├── data │ ├── bio-list.json │ ├── category.json │ ├── com-list.json │ ├── eco-list.json │ ├── latest.json │ └── mag-list.json ├── fonts │ ├── ionicons.eot │ ├── ionicons.svg │ ├── ionicons.ttf │ └── ionicons.woff ├── images │ ├── adam.jpg │ ├── ben.png │ ├── bg-book.png │ ├── carousel │ │ ├── biol01.jpg │ │ ├── biol02.jpg │ │ ├── biol03.jpg │ │ ├── biol04.jpg │ │ ├── biol05.jpg │ │ ├── comp01.jpg │ │ ├── comp02.jpg │ │ ├── comp03.jpg │ │ ├── comp04.jpg │ │ ├── comp05.jpg │ │ ├── econ01.jpg │ │ ├── econ02.jpg │ │ ├── econ03.jpg │ │ ├── econ04.jpg │ │ ├── econ05.jpg │ │ ├── latest01.jpg │ │ ├── latest02.jpg │ │ ├── latest03.jpg │ │ ├── latest04.jpg │ │ └── latest05.jpg │ ├── icon-mp3.png │ ├── ionic.png │ ├── max.png │ ├── mike.png │ ├── perry.png │ ├── play-btn.png │ ├── post-bg.gif │ └── transparent.gif ├── index.html ├── manifest.json └── service-worker.js └── yarn.lock /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "src/lib" 3 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | node_modules/ 5 | platforms/ 6 | plugins/ 7 | src/lib 8 | *.log 9 | .DS_Store 10 | .sourcemaps -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 NY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ionic v1 tab app template demo 2 | 3 | ## Branches 4 | 5 | - Current branch is **ionic-v1**, switch to [ionic-angular branch](https://github.com/johnnynode/ionic-samples/tree/ionic-angular) 6 | 7 | ## Clone 8 | 9 | - $ `git clone -b ionic-v1 git@github.com:johnnynode/ionic-sample.git --depth 1` 10 | 11 | ## Install 12 | 13 | - $ `cd ionic-sample` 14 | - $ `yarn install` or $ `npm i` or $ `cnpm i` 15 | - $ `bower install --force` (manual operation not in npm scripts) 16 | 17 | ## Run 18 | 19 | - $ `gulp server` 20 | 21 | ## Build 22 | 23 | - $ `gulp build` 24 | 25 | ## Build-server 26 | 27 | - $ `gulp build-server` 28 | 29 | ## Beware 30 | 31 | - pdf url may need cross the wall if you are in China: https://mozilla.github.io/pdf.js/web/viewer.html 32 | - video url is from videogular: http://static.videogular.com/assets/videos/videogular.mp4 33 | - music url is a local file in `src/media/audio/music.mp3` 34 | - about cross domain, see more @ api of [gulp-connect](https://github.com/AveVlad/gulp-connect) 35 | 36 | ## PdfLoading 37 | 38 |
39 | PdfLoading Blog 40 |
41 |
42 | 43 |
44 | 45 | ## AudioPlay 46 | 47 |
48 | AudioPlay Blog 49 |
50 |
51 | 52 |
53 | 54 | ## VideoPlay 55 | 56 |
57 | VideoPlay Blog 58 |
59 |
60 | 61 |
62 | 63 | ## CategoryScrolling 64 | 65 |
66 | CategoryScrolling Blog 67 |
68 |
69 | 70 |
71 | 72 | ## CarouselScaleBanners 73 | 74 |
75 | CarouselScaleBanners Blog 76 |
77 |
78 | 79 |
80 | 81 | ## About Splash 82 | 83 | - [ionic-splash-demo@johnnynode](https://github.com/johnnynode/ionic-splash-demo) 84 | 85 | ## More Samples 86 | 87 | coming soon... 88 | 89 | ## License 90 | 91 | MIT -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-sample", 3 | "private": "true", 4 | "dependencies": { 5 | "ionic": "^1.3.2", 6 | "ngCordova": "^0.1.27-alpha", 7 | "angular-cookies": "#1.5.8", 8 | "ionic-native-transitions": "shprink/ionic-native-transitions#^1.0.2", 9 | "ionic-image-lazy-load": "ion-image-lazy-load#*" 10 | }, 11 | "overrides": { 12 | "ionic": { 13 | "main": [ 14 | "release/css/ionic.min.css", 15 | "release/js/ionic.bundle.min.js" 16 | ] 17 | }, 18 | "angular":{ 19 | "ignore":true 20 | }, 21 | "angular-animate":{ 22 | "ignore":true 23 | }, 24 | "angular-sanitize":{ 25 | "ignore":true 26 | }, 27 | "angular-ui-router":{ 28 | "ignore":true 29 | } 30 | }, 31 | "resolutions": { 32 | "angular": ">= 1.0.8" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ionic-sample 4 | 5 | An Ionic Framework and Cordova project. 6 | 7 | 8 | Your Name Here 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | //引入插件 2 | var gulp = require('gulp'), 3 | connect = require('gulp-connect'), 4 | proxy = require('http-proxy-middleware'), 5 | plumber = require('gulp-plumber'), 6 | process = require('process'), 7 | runSequence = require('run-sequence'), 8 | watch = require('gulp-watch'), 9 | imagemin = require('gulp-imagemin'), // 压缩image 10 | sass = require('gulp-sass'), // sass 文件处理 11 | cleanCSS = require('gulp-clean-css'), // 压缩css 12 | concat = require('gulp-concat'), 13 | htmlmin = require('gulp-htmlmin'), // 压缩html 14 | uglify = require('gulp-uglify'), // 压缩js 15 | gutil = require('gulp-util'), 16 | bowerFiles = require('main-bower-files'), // bower相关文件处理 17 | postcss = require('gulp-postcss'), 18 | autoprefixer = require('autoprefixer'), 19 | htmlreplace = require('gulp-html-replace'), 20 | inject = require('gulp-inject'), 21 | templateCache = require('gulp-angular-templatecache'), 22 | ngAnnotate = require('gulp-ng-annotate'), 23 | del = require('del'), // 清空文件和文件夹 24 | open = require('gulp-open'), 25 | order = require("gulp-order"), // 判断引入优先级 26 | stripDebug = require('gulp-strip-debug'), // Strip console, alert, and debugger statements 27 | _if = require('gulp-if'); // 引用判断 28 | 29 | var platform = process.platform, // 判断操作系统 30 | // 定义一组browser的判断 31 | browser = platform === 'linux' ? 'google-chrome' : ( 32 | platform === 'darwin' ? 'google chrome' : ( 33 | platform === 'win32' ? 'chrome' : 'firefox')), 34 | // 定义标识 35 | connectFlag = 0, // 用于控制connect任务中的root路径 36 | portFlag = 0, // 用于控制端口不同 37 | timeStamp = new Date().getTime(); // 添加时间戳,标识每次构建生成的不同的文件 38 | 39 | // 定义所有的路径 40 | var allPath = { 41 | src: './src', 42 | dist: './www', 43 | watchPath:['./src', './bower.json'], 44 | index:'./src/index.html', 45 | fonts:['./src/fonts/**/*', './src/lib/ionic/release/fonts/**/*'], 46 | // 用于替换的路径 47 | replacePath: { 48 | 'bowerCss': 'app/vendor.' + timeStamp + '.min.css', 49 | 'appCss':'app/app.' + timeStamp + '.min.css', 50 | 'bowerJs':'app/vendor.' + timeStamp + '.min.js', 51 | 'appJs': 'app/app.' + timeStamp + '.min.js', 52 | 'templates': 'app/app.templates.' + timeStamp + '.min.js' 53 | }, 54 | // 图片路径 55 | images: './src/images/**', 56 | // css路径 57 | appCss: './src/css/**/*.css', 58 | // js 路径 59 | appJs: ['./src/js/**/*.js', './src/components/**/*.js', './src/pages/**/*.js', '!./src/js/app.templates.js'], 60 | // html 模板路径 61 | templates:['./src/pages/**/*.html'] 62 | }; 63 | 64 | // 定义动态插入的路径 65 | allPath.injectPath = { 66 | 'bowerFiles': bowerFiles(), 67 | 'appCss': allPath.appCss, 68 | 'appJs': allPath.appJs 69 | }; 70 | 71 | // 生产模式任务 72 | var productionTask = ["index", "data", "images", "fonts", "bower-files", "app-css", "app-js", "templates", "audio"]; 73 | 74 | // 处理index.html相关引入脚本,包括样式和脚本 75 | gulp.task('index', function () { 76 | return gulp.src(allPath.index) 77 | .pipe(plumber()) 78 | .pipe(htmlreplace(allPath.replacePath)) 79 | .pipe(htmlmin({collapseWhitespace: true})) 80 | .pipe(gulp.dest(allPath.dist + '/.')); 81 | }); 82 | 83 | // 处理图片 84 | gulp.task('images', function() { 85 | return gulp.src(allPath.images) 86 | .pipe(plumber()) 87 | .pipe(imagemin()) 88 | .pipe(gulp.dest(allPath.dist + '/images')); 89 | }); 90 | 91 | // 处理字体图标 92 | gulp.task('fonts', function() { 93 | return gulp.src(allPath.fonts) 94 | .pipe(plumber()) 95 | .pipe(gulp.dest(allPath.dist + '/fonts/')); 96 | }); 97 | 98 | // 处理bower相关的样式和脚本构建, 只针对css和js进行处理 99 | gulp.task('bower-files', function() { 100 | return gulp.src(allPath.injectPath.bowerFiles) 101 | .pipe(plumber()) 102 | .pipe(order(["ionic.bundle.min.js"])) 103 | .pipe(_if('*.css', cleanCSS({rebase: true}))) 104 | .pipe(_if('*.css', concat(allPath.replacePath.bowerCss))) 105 | .pipe(_if('*.css', gulp.dest(allPath.dist + '/.'))) 106 | .pipe(_if('*.js', uglify())) 107 | .pipe(_if('*.js', concat(allPath.replacePath.bowerJs))) 108 | .pipe(_if('*.js', gulp.dest(allPath.dist + '/.'))) 109 | }); 110 | 111 | // 处理app 样式 112 | gulp.task('app-css', function() { 113 | return gulp.src(allPath.appCss) 114 | .pipe(plumber()) 115 | // todo sass 116 | .pipe(cleanCSS({rebase: true})) 117 | .pipe(postcss([autoprefixer()])) 118 | .pipe(concat(allPath.replacePath.appCss)) 119 | .pipe(gulp.dest(allPath.dist + '/.')); 120 | }); 121 | 122 | // 处理 appjs 123 | gulp.task('app-js', function() { 124 | return gulp.src(allPath.appJs) 125 | .pipe(plumber()) 126 | .pipe(ngAnnotate()) 127 | .pipe(stripDebug()) 128 | .pipe(uglify()) 129 | .pipe(concat(allPath.replacePath.appJs)) 130 | .pipe(gulp.dest(allPath.dist + '/.')); 131 | }); 132 | 133 | // 压缩 html 并将它们模板化 134 | gulp.task('templates', function() { 135 | return gulp.src(allPath.templates) 136 | .pipe(plumber()) 137 | .pipe(htmlmin({ collapseWhitespace: true })) 138 | .pipe(templateCache({ 139 | standalone: true, 140 | root: 'pages' 141 | })) 142 | .pipe(uglify()) 143 | .pipe(concat(allPath.replacePath.templates)) 144 | .pipe(gulp.dest(allPath.dist + '/.')); 145 | }); 146 | 147 | // 插入任务 148 | gulp.task('inject', function () { 149 | gulp.src(allPath.index) 150 | .pipe(plumber()) 151 | // 注入bower相关的 css 和 js 152 | .pipe(inject(gulp.src(allPath.injectPath.bowerFiles, {read: false}).pipe(order(["ionic.bundle.min.js"])), {name:'bower', relative: true})) 153 | // 注入自己模块的css 154 | .pipe(inject(gulp.src(allPath.injectPath.appCss, {read: false}), {starttag: '', relative: true})) 155 | // 注入自己模块的js 156 | .pipe(inject(gulp.src(allPath.injectPath.appJs, {read: false}), {starttag: '', relative: true})) 157 | .pipe(gulp.dest(allPath.src)) 158 | }); 159 | 160 | // clean task 161 | gulp.task('clean', function() { 162 | return del([ 163 | allPath.dist 164 | ]); 165 | }); 166 | 167 | // 使用connect启动一个Web服务器 168 | gulp.task('connect', function() { 169 | var root = connectFlag ? allPath.dist : allPath.src, 170 | hostname = '127.0.0.1'; 171 | connect.server({ 172 | root: root, 173 | fallback: root + '/index.html', 174 | host: hostname, 175 | livereload: { 176 | hostname: hostname, 177 | enable: true, 178 | port: portFlag ? 36000 : 35729 179 | }, 180 | port: portFlag ? 8012 : 9012, 181 | middleware: function(connect, opt) { 182 | return [ 183 | /* 184 | // 这里做跨域处理 185 | proxy(["/api"], { 186 | target: '', 187 | changeOrigin: true, 188 | pathRewrite: { 189 | '^/api': '/' 190 | } 191 | }) 192 | */ 193 | ] 194 | } 195 | }); 196 | }); 197 | 198 | // 监控任务 199 | gulp.task('watch', function() { 200 | gulp.src(allPath.src) 201 | .pipe(plumber()) 202 | .pipe(watch(allPath.watchPath,function (vinyl) { 203 | var type = vinyl.event; 204 | // 监控添加和移除的加入 205 | if (type === 'add' || type === 'unlink') { 206 | runSequence(['inject']); // 执行插入功能 207 | } 208 | })) 209 | .pipe(connect.reload()); 210 | }); 211 | 212 | // 复制任务 213 | gulp.task('copy', function() { 214 | return gulp.src(allPath.src + '/**') 215 | .pipe(plumber()) 216 | .pipe(gulp.dest(allPath.dist + '/')); 217 | }); 218 | 219 | // 复制数据任务,在实际项目中不存在 220 | gulp.task('data', function() { 221 | return gulp.src(allPath.src + '/data/**') 222 | .pipe(plumber()) 223 | .pipe(gulp.dest(allPath.dist + '/data')); 224 | }); 225 | 226 | // audio 任务 根据原项目添加,大部分情况是线上的,不会存在这个任务 227 | gulp.task('audio', function() { 228 | return gulp.src(allPath.src + '/audio/**', { base: allPath.src }) 229 | .pipe(plumber()) 230 | .pipe(gulp.dest(allPath.dist + '/')); 231 | }); 232 | 233 | // 打开浏览器的任务 234 | gulp.task('open', function() { 235 | // gulp-open 的选项 236 | var browserOptions = { 237 | uri: 'http://127.0.0.1:' + (portFlag ? '8012' : '9012'), 238 | app: browser 239 | }; 240 | gulp.src(allPath.src) 241 | .pipe(open(browserOptions)); 242 | }); 243 | 244 | //运行Gulp时,搭建起跨域服务器 开发模式下 245 | gulp.task('server', function() { 246 | connectFlag = 0; 247 | portFlag = 0; 248 | runSequence(['connect', 'watch', 'inject', 'open']); 249 | }); 250 | 251 | // 开始构建 todo 252 | gulp.task('build', ['clean'], function() { 253 | console.time('build'); 254 | gutil.log(gutil.colors.yellow('🚄 构建开始!')); 255 | runSequence(productionTask, function() { 256 | gutil.log(gutil.colors.yellow('🔥 构建完成,总共用时:')); 257 | console.timeEnd('build'); 258 | }); 259 | }); 260 | 261 | // 构建之后开启服务器 262 | gulp.task('build-server', function() { 263 | connectFlag = 1; 264 | portFlag = 1; 265 | runSequence(['connect', 'open']); 266 | }); -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | 21 | # Cordova Hooks 22 | 23 | This directory may contain scripts used to customize cordova commands. This 24 | directory used to exist at `.cordova/hooks`, but has now been moved to the 25 | project root. Any scripts you add to these directories will be executed before 26 | and after the commands corresponding to the directory name. Useful for 27 | integrating your own build systems or integrating with version control systems. 28 | 29 | __Remember__: Make your scripts executable. 30 | 31 | ## Hook Directories 32 | The following subdirectories will be used for hooks: 33 | 34 | after_build/ 35 | after_compile/ 36 | after_docs/ 37 | after_emulate/ 38 | after_platform_add/ 39 | after_platform_rm/ 40 | after_platform_ls/ 41 | after_plugin_add/ 42 | after_plugin_ls/ 43 | after_plugin_rm/ 44 | after_plugin_search/ 45 | after_prepare/ 46 | after_run/ 47 | after_serve/ 48 | before_build/ 49 | before_compile/ 50 | before_docs/ 51 | before_emulate/ 52 | before_platform_add/ 53 | before_platform_rm/ 54 | before_platform_ls/ 55 | before_plugin_add/ 56 | before_plugin_ls/ 57 | before_plugin_rm/ 58 | before_plugin_search/ 59 | before_prepare/ 60 | before_run/ 61 | before_serve/ 62 | pre_package/ <-- Windows 8 and Windows Phone only. 63 | 64 | ## Script Interface 65 | 66 | All scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables: 67 | 68 | * CORDOVA_VERSION - The version of the Cordova-CLI. 69 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios). 70 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer) 71 | * CORDOVA_HOOK - Path to the hook that is being executed. 72 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate) 73 | 74 | If a script returns a non-zero exit code, then the parent cordova command will be aborted. 75 | 76 | 77 | ## Writing hooks 78 | 79 | We highly recommend writting your hooks using Node.js so that they are 80 | cross-platform. Some good examples are shown here: 81 | 82 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) 83 | 84 | -------------------------------------------------------------------------------- /hooks/after_prepare/010_add_platform_class.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Add Platform Class 4 | // v1.0 5 | // Automatically adds the platform class to the body tag 6 | // after the `prepare` command. By placing the platform CSS classes 7 | // directly in the HTML built for the platform, it speeds up 8 | // rendering the correct layout/style for the specific platform 9 | // instead of waiting for the JS to figure out the correct classes. 10 | 11 | var fs = require('fs'); 12 | var path = require('path'); 13 | 14 | var rootdir = process.argv[2]; 15 | 16 | function addPlatformBodyTag(indexPath, platform) { 17 | // add the platform class to the body tag 18 | try { 19 | var platformClass = 'platform-' + platform; 20 | var cordovaClass = 'platform-cordova platform-webview'; 21 | 22 | var html = fs.readFileSync(indexPath, 'utf8'); 23 | 24 | var bodyTag = findBodyTag(html); 25 | if(!bodyTag) return; // no opening body tag, something's wrong 26 | 27 | if(bodyTag.indexOf(platformClass) > -1) return; // already added 28 | 29 | var newBodyTag = bodyTag; 30 | 31 | var classAttr = findClassAttr(bodyTag); 32 | if(classAttr) { 33 | // body tag has existing class attribute, add the classname 34 | var endingQuote = classAttr.substring(classAttr.length-1); 35 | var newClassAttr = classAttr.substring(0, classAttr.length-1); 36 | newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; 37 | newBodyTag = bodyTag.replace(classAttr, newClassAttr); 38 | 39 | } else { 40 | // add class attribute to the body tag 41 | newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); 42 | } 43 | 44 | html = html.replace(bodyTag, newBodyTag); 45 | 46 | fs.writeFileSync(indexPath, html, 'utf8'); 47 | 48 | process.stdout.write('add to body class: ' + platformClass + '\n'); 49 | } catch(e) { 50 | process.stdout.write(e); 51 | } 52 | } 53 | 54 | function findBodyTag(html) { 55 | // get the body tag 56 | try{ 57 | return html.match(/])(.*?)>/gi)[0]; 58 | }catch(e){} 59 | } 60 | 61 | function findClassAttr(bodyTag) { 62 | // get the body tag's class attribute 63 | try{ 64 | return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0]; 65 | }catch(e){} 66 | } 67 | 68 | if (rootdir) { 69 | 70 | // go through each of the platform directories that have been prepared 71 | var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); 72 | 73 | for(var x=0; x 2 | 3 | 4 |
5 | 6 |
7 | 8 |
9 |
10 | {{audioData.current ? audioData.current : '00:00:00'}} 11 | {{audioData.duration ? audioData.duration : '00:00:00'}} 12 |
13 |
14 |
15 | 16 |
17 |
18 | 19 | -------------------------------------------------------------------------------- /src/components/directives/html/video.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 6 | 7 |
8 | 9 |
10 | 11 |
12 |
13 | {{videoData.current ? videoData.current : '00:00:00'}}/{{videoData.duration ? videoData.duration : '00:00:00'}} 14 |
15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /src/components/directives/js/carousel.js: -------------------------------------------------------------------------------- 1 | (function (angular) { 2 | "use strict"; 3 | // 定义一些通用的指令 4 | angular.module('ionic-samples') 5 | .directive('homeSlider', function (settings, $compile, $timeout) { 6 | return { 7 | restrict: 'A', 8 | scope: { 9 | volList: '=', 10 | charShow: '=' 11 | }, 12 | template: '
', 13 | link: function (scope) { 14 | // 所有设置函数 15 | function setUp(){ 16 | // 针对宽高比的判断 17 | var flag = window.innerWidth / window.innerHeight < 360/590; // 针对一些非常规手机的处理 18 | // 进行轮播图的 dom 生成操作 19 | var $ = angular.element; // jqLite 对象 20 | var slideBox = document.querySelector('.slider-wrap'); // 获取轮播盒子对象 21 | var sliderInner = document.createElement('ul'); 22 | sliderInner.className = 'slider-wrap-inner'; 23 | slideBox.appendChild(sliderInner); 24 | 25 | // 去详情页方法 26 | scope.goPreview = function (vol, magCode, title) { 27 | $timeout(function(){ 28 | settings.setUtils().go('preview', {vol: vol, magCode: magCode, title: title}); 29 | }); 30 | }; 31 | 32 | // 缩放的动画 33 | function scale(obj, rate) { 34 | if (!obj) return; 35 | obj.style.transform = "scale(" + rate + ")"; 36 | obj.style.webkitTransform = "scale(" + rate + ")"; 37 | } 38 | 39 | // 获取数据 40 | function getData(list, callback) { 41 | // 通过获得的数据,生成节点操作 42 | for (var i = 0; i < list.length; i++) { 43 | var li = document.createElement('li'); 44 | var img = document.createElement('img'); 45 | var imgWrap = document.createElement('div'); 46 | imgWrap.className = 'img-wrap'; 47 | img.src = 'images/transparent.gif'; 48 | // 首先先加载前三张图片的地址,其他的作懒加载处理 49 | if (i < 3) { 50 | img.setAttribute('style', 'background-image:url(' + list[i].coverimg + ')'); 51 | } 52 | imgWrap.appendChild(img); 53 | li.appendChild(imgWrap); 54 | li.setAttribute('on-tap', 'goPreview("' + list[i].vol + '","' + list[i].magCode + '","' + list[i].title + '")'); // 绑定事件 55 | // 根据屏幕尺寸来显示隐藏title 56 | if(flag){ 57 | var title = document.createElement('div'); 58 | title.innerHTML = list[i].title; 59 | title.className = 'vol-title'; 60 | li.appendChild(title); 61 | } 62 | $(sliderInner).append($(li)); 63 | } 64 | var htmlObj = $compile($(sliderInner).html())(scope); // 对html 进行重新编译 65 | $(sliderInner).html(''); // 清空 66 | $(sliderInner).append(htmlObj); // 追加 67 | var lis = sliderInner.querySelectorAll('li'); // 得到当前的所有li对象 68 | var imgs = []; // 用于存放图像包裹节点 69 | // 图像包裹节点数组, 初始化样式 70 | for (var k = 0; k < lis.length; k++) { 71 | if (!k) { 72 | imgs.push(lis[0].querySelector('.img-wrap')); // 第一个只 push 进去 ,不 设置样式 73 | continue; 74 | } 75 | var item = lis[k].querySelector('.img-wrap'); 76 | scale(item, 252 / 291); // 样式初始化缩放 77 | imgs.push(item); // 并push 78 | } 79 | callback && angular.isFunction(callback) ? callback(imgs, list) : ''; // 将数据通过callback带走 80 | } 81 | 82 | // 针对杂志切换,数据同时切换 83 | scope.$watch('volList', function (now) { 84 | if (now && now.length) { 85 | sliderInner.innerHTML = ''; // 先清空内容 86 | // 使用$timeout来解决宽度问题,重新渲染dom. 87 | $timeout(function(){ 88 | getData(now, function (imgs, now) { 89 | var m = new MobileMove(); // 重新new 90 | m.setSwipe(slideBox, sliderInner, imgs, now); 91 | }); 92 | }); 93 | } 94 | }); 95 | } 96 | 97 | // 页面加载完成后执行 98 | var contentLoaded = scope.$watch('$viewContentLoaded', function() { 99 | setUp(); // 全面设置 100 | contentLoaded(); // 取消 watch 101 | }); 102 | } 103 | }; 104 | }) 105 | })(angular); 106 | -------------------------------------------------------------------------------- /src/components/directives/js/mp3.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | "use strict"; 3 | angular.module('ionic-samples') 4 | .directive('mp3Container', function($timeout, appUtils) { 5 | return { 6 | restrict: 'EA', 7 | templateUrl: 'components/directives/html/mp3.html', 8 | scope: { 9 | source: '=' 10 | }, 11 | link: function(scope, element) { 12 | // 初始化变量和数据成员 13 | var audio = element.find('audio')[0]; // 获取视频元素 14 | var audioData = scope.audioData = {}; 15 | audioData.playing = false; // 控制是否播放中 16 | audioData.currentOrigin = 0; // 当前播放进度 17 | 18 | /* 播放与暂停 */ 19 | scope.play = function() { 20 | if (!audioData.playing) { 21 | audio.autoplay = audioData.playing = true; 22 | audio.play(); 23 | scope.$emit('audio:playState', true); // 发送广播 24 | } else { 25 | audio.autoplay = audioData.playing = false; 26 | audio.pause(); 27 | scope.$emit('audio:playState', false); // 发送广播 28 | } 29 | }; 30 | 31 | // 滑动功能实现 32 | scope.seeking = function() { 33 | audio.currentTime = audioData.currentOrigin; 34 | }; 35 | 36 | // 事件监听: loadstart 37 | ionic.EventController.on('loadstart', function() {}, audio); 38 | 39 | // 事件监听: 元数据加载完成后 此时获取时长 40 | ionic.EventController.on('loadedmetadata', function() { 41 | appUtils.checkToGetMediaDuration(scope, audio, audioData); 42 | this.autoplay = audioData.playing = false; // 为了兼容 43 | scope.$apply(); 44 | }, audio); 45 | 46 | // 事件监听: durationchange 47 | ionic.EventController.on('durationchange', function() { 48 | appUtils.checkToGetMediaDuration(scope, audio, audioData); 49 | this.autoplay = true; // 为了兼容 50 | scope.$apply(); 51 | }, audio); 52 | 53 | // 事件监听: onprogress 正在下载中 54 | ionic.EventController.on('progress', function() { 55 | appUtils.checkToGetMediaDuration(scope, audio, audioData); 56 | scope.$apply(); 57 | }, audio); 58 | 59 | // 事件监听: waiting 60 | ionic.EventController.on('waiting', function() { 61 | this.autoplay = audioData.playing = false; 62 | scope.$apply(); 63 | }, audio); 64 | 65 | // 事件监听: seeking 66 | ionic.EventController.on('seeking', function() { 67 | audioData.playing = this.autoplay = false; // 为了兼容 = true ; 无法继续播放时loading ; seeking 保持播放状态 68 | scope.$emit('audio:playState', false); // 发送广播 69 | $timeout(function() { 70 | audio.play(); // 强制播放 71 | scope.$emit('audio:playState', true); // 发送广播 72 | }); 73 | scope.$apply(); 74 | }, audio); 75 | 76 | // 事件监听: 在可播放时 只会触发一次 , 播放按钮状态 : 可播放 77 | ionic.EventController.on('playing', function() { 78 | appUtils.checkToGetMediaDuration(scope, audio, audioData); 79 | this.autoplay = audioData.playing = true; // 为了兼容 此处 loading 应为false,但安卓低端机器存在问题 80 | scope.$emit('audio:playState', true); // 发送广播 81 | scope.$apply(); 82 | }, audio); 83 | 84 | // 事件监听: 监听暂停事件 85 | ionic.EventController.on('pause', function() { 86 | audioData.playing = false; 87 | scope.$apply(); 88 | }, audio); 89 | 90 | // 事件监听: 音频播放位置发生改变时触发 91 | ionic.EventController.on('timeupdate', function() { 92 | appUtils.checkToGetMediaDuration(scope, audio, audioData); 93 | audioData.currentOrigin = audio.currentTime; // 获取视频当前时间 94 | audioData.current = appUtils.handlePlayingTime(audio.currentTime); // 获取格式转换之后的视频当前时间 95 | scope.$apply(); 96 | }, audio); 97 | 98 | // 事件监听: 视频可以流畅播放到结束 99 | ionic.EventController.on('canplaythrough', function() {}, audio); 100 | 101 | // 事件监听: 视频可以流畅播放 102 | ionic.EventController.on('canplay', function() {}, audio); 103 | 104 | // 事件监听: 播放完成 105 | ionic.EventController.on('ended', function() { 106 | this.pause(); 107 | scope.$emit('audio:playState', false); // 发送广播 108 | scope.$apply(); 109 | }, audio); 110 | } 111 | }; 112 | }); 113 | })(angular); 114 | -------------------------------------------------------------------------------- /src/components/directives/js/video.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | "use strict"; 3 | angular.module('ionic-samples') 4 | .directive('videoContainer', function(appUtils) { 5 | return { 6 | restrict: 'EA', 7 | templateUrl: 'components/directives/html/video.html', 8 | scope: { 9 | source: '=' 10 | }, 11 | link: function(scope, element) { 12 | // 初始化数据成员 13 | // 视频默认是要点击后播放的 14 | var video = element.find('video')[0]; // 获取视频元素 15 | var videoFlag = 0; // 用于检测video播放 16 | var videoData = scope.videoData = {}; 17 | videoData.playing = false; // 控制是否播放中 18 | videoData.currentOrigin = 0; // 当前播放进度 19 | 20 | // 点击播放按钮或暂停功能 21 | scope.play = function() { 22 | if (!videoData.playing) { 23 | video.autoplay = videoData.playing = true; 24 | video.play(); 25 | } else { 26 | video.autoplay = videoData.playing = false; 27 | video.pause(); 28 | } 29 | }; 30 | 31 | // 滑动功能实现 32 | scope.seeking = function() { 33 | video.currentTime = videoData.currentOrigin; 34 | videoFlag = 0; 35 | }; 36 | 37 | // 事件监听 38 | // 开始播放 , 初始化所有数据 39 | ionic.EventController.on('loadstart', function() { 40 | videoData.playing = this.autoplay = false; // 默认是播放状态,同loading 41 | videoData.isLoading = true; // 开始loading 42 | scope.$apply(); 43 | }, video); 44 | 45 | // 元数据加载完成后 此时获取时长 46 | ionic.EventController.on('loadedmetadata', function() { 47 | appUtils.checkToGetMediaDuration(scope, video, videoData); 48 | videoFlag = 0; // 此处归零 表示视频 49 | this.autoplay = videoData.isLoading = false; // 为了兼容 50 | scope.$apply(); 51 | }, video); 52 | 53 | ionic.EventController.on('durationchange', function() { 54 | appUtils.checkToGetMediaDuration(scope, video, videoData); 55 | this.autoplay = true; // 为了兼容 56 | scope.$apply(); 57 | }, video); 58 | 59 | // onprogress 正在下载中 60 | ionic.EventController.on('progress', function() { 61 | appUtils.checkToGetMediaDuration(scope, video, videoData); 62 | scope.$apply(); 63 | }, video); 64 | 65 | // waiting 66 | ionic.EventController.on('waiting', function() { 67 | videoData.isLoading = this.autoplay = true; // 为了兼容 true; // 无法继续播放时loading 68 | videoData.playing = true; // 同样保持播放状态 69 | scope.$apply(); 70 | }, video); 71 | 72 | // seeking 73 | ionic.EventController.on('seeking', function() { 74 | videoData.isLoading = videoData.playing = this.autoplay = true; // 为了兼容 = true ; 无法继续播放时loading ; seeking 保持播放状态 75 | this.play(); // 强制播放 76 | scope.$apply(); 77 | }, video); 78 | 79 | // 在可播放时 只会触发一次 , 播放按钮状态 : 可播放 80 | ionic.EventController.on('playing', function() { 81 | appUtils.checkToGetMediaDuration(scope, video, videoData); 82 | this.autoplay = videoData.isLoading = true; // 为了兼容 此处 loading 应为 false ,但安卓低端机器存在问题 83 | scope.$apply(); 84 | }, video); 85 | 86 | // 监听暂停事件 87 | ionic.EventController.on('pause', function() { 88 | videoData.playing = videoData.isLoading = false; 89 | scope.$apply(); 90 | }, video); 91 | 92 | // 音频播放位置发生改变时触发 93 | 94 | /* 设置为自动隐藏 */ 95 | ionic.EventController.on('timeupdate', function() { 96 | appUtils.checkToGetMediaDuration(scope, video, videoData); 97 | videoData.currentOrigin = video.currentTime; // 获取视频当前时间 98 | videoData.current = appUtils.handlePlayingTime(video.currentTime); // 获取格式转换之后的视频当前时间 99 | 100 | if (videoFlag >= 1) { // timeupdate 时,开始播放 兼容问题 101 | videoData.isLoading = false; 102 | videoData.playing = true; // 播放按钮呈现 103 | } 104 | 105 | if (videoFlag === 10) { 106 | videoData.hide = true; 107 | scope.$emit('videoBarHide', 1); // 发送广播, 隐藏bar 108 | } 109 | 110 | videoFlag++; 111 | scope.$apply(); 112 | }, video); 113 | 114 | // 触摸取消隐藏 115 | ionic.EventController.on('touchstart', function() { 116 | videoFlag = 0; 117 | scope.$emit('videoBarShow', 1); // 发送广播, 显示bar 118 | }, video); 119 | 120 | // 视频可以流畅播放到结束 121 | ionic.EventController.on('canplaythrough', function() {}, video); 122 | 123 | // 视频可以流畅播放 124 | ionic.EventController.on('canplay', function() {}, video); 125 | 126 | // 播放完成 127 | ionic.EventController.on('ended', function() { 128 | this.pause(); 129 | scope.hide = false; // 显示 130 | scope.$apply(); 131 | }, video); 132 | } 133 | }; 134 | }); 135 | })(angular); 136 | -------------------------------------------------------------------------------- /src/css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/css/.DS_Store -------------------------------------------------------------------------------- /src/css/category.css: -------------------------------------------------------------------------------- 1 | .items-content .items-title { 2 | background: #F2F2F2; 3 | height: 22px; 4 | padding: 0 10px; 5 | line-height: 22px; 6 | color: #808080; 7 | font-size: 16px; 8 | } 9 | 10 | .items-content .items-item { 11 | font-size: 15px; 12 | color: #808080; 13 | padding-left: 70px; 14 | height: 60px; 15 | line-height: 30px; 16 | } 17 | 18 | .category .items-content .items-item { 19 | font-size: 15px; 20 | color: #808080; 21 | padding-left: 12px; 22 | height: 60px; 23 | line-height: 30px; 24 | border: none; 25 | margin: 0 0 1px 12px; 26 | } 27 | 28 | .category .items-content .items-item .icon-item-logo { 29 | height: 44px; 30 | width: 44px; 31 | top: 8px; 32 | left: 11px; 33 | font-size: 22px; 34 | color: #e2e2e2; 35 | } 36 | 37 | .category .icon-item-logo:before { 38 | position: absolute; 39 | content: 'LOGO'; 40 | width: 100% !important; 41 | top: 0; 42 | left: 0; 43 | text-align: center; 44 | font-size: 12px; 45 | line-height: 45px; 46 | color: #9e9e9e; 47 | font-family: 'Helvetica'; 48 | } 49 | 50 | .category .icon-item-logo:after { 51 | border-radius: 50%; 52 | border-color: #666; 53 | } 54 | 55 | .category .items-item-one { 56 | margin-bottom: -2px; 57 | } 58 | 59 | .category .items-item-one .list .item:last-child:after { 60 | display: none; 61 | } 62 | 63 | /* 悬浮的abc */ 64 | .fixed-abc { 65 | position: fixed; 66 | z-index: 999; 67 | top: 50%; 68 | transform: translateY(-50%); 69 | -webkit-transform: translateY(-50%); 70 | right: 10px; 71 | font-size: 12px; 72 | font-weight: 500; 73 | text-align: center; 74 | padding: 0 6px; 75 | } 76 | 77 | .category .fixed-abc li { 78 | height: 16px; 79 | line-height: 16px; 80 | } 81 | 82 | .category .letterShow { 83 | position: fixed; 84 | width: 80px; 85 | height: 80px; 86 | line-height: 80px; 87 | text-align: center; 88 | border: 1px solid #c1c1c1; 89 | border-radius: 6px; 90 | font-size: 28px; 91 | transition: all .2s ease 0s; 92 | -webkit-transition: all .2s ease 0s; 93 | opacity: 0; 94 | z-index: -1; 95 | } 96 | 97 | .category .letterShow.cur { 98 | opacity: 1; 99 | z-index: 9999; 100 | background-color: #fff; 101 | } 102 | 103 | .category ion-content .scroll{ 104 | background-color: #fff; 105 | } 106 | -------------------------------------------------------------------------------- /src/css/samples.carousel.css: -------------------------------------------------------------------------------- 1 | .carousel .slider-wrap { 2 | width: 100%; 3 | height: auto; 4 | overflow-x: scroll; 5 | white-space: nowrap; 6 | } 7 | 8 | .carousel .slider-wrap::-webkit-scrollbar { 9 | display: none; 10 | } 11 | 12 | .carousel .slider-wrap-inner { 13 | width: 100%; 14 | white-space: nowrap; 15 | font-size: 0; 16 | } 17 | 18 | .carousel .slider-wrap-inner > li { 19 | width: 77.6%; 20 | margin: 0; 21 | display: inline-block; 22 | vertical-align: top; 23 | } 24 | 25 | .carousel .slider-wrap-inner img { 26 | display: inline-block; 27 | vertical-align: middle; 28 | height: 3.3rem; 29 | width: 100%; 30 | background-color: #f2f2f2; 31 | background-size: 100% auto; 32 | background-repeat: no-repeat; 33 | background-position: center bottom; 34 | } 35 | 36 | .carousel .slider-wrap-inner .img-wrap { 37 | padding: 0 10px 12px 0; 38 | background: url('../images/bg-book.png') right bottom no-repeat; 39 | background-size: 100% auto; 40 | } 41 | 42 | .carousel .slider-wrap-inner li:first-child { 43 | margin-left: 12%; 44 | } 45 | 46 | .carousel .slider-wrap-inner li:last-child { 47 | margin-right: 12.8%; 48 | } 49 | 50 | .carousel .vol-title { 51 | text-align: center; 52 | font-size: 14px; 53 | line-height: 16px; 54 | margin: 5% 0; 55 | color: #4D4D4D; 56 | letter-spacing: 0; 57 | } 58 | 59 | @media (max-height: 500px) { 60 | .carousel .magazine-slider { 61 | transform: translateY(-40%); 62 | -webkit-transform: translateY(-40%); 63 | } 64 | 65 | .carousel .vol-title { 66 | margin: 7% 0; 67 | } 68 | } 69 | 70 | /* iphone 6s 及 plus */ 71 | @media (min-width: 375px){ 72 | .carousel .slider-wrap-inner img{ 73 | height: 3.46rem; 74 | } 75 | } 76 | 77 | .carousel .magazine-wrap { 78 | text-align: center; 79 | line-height: 44px; 80 | width: 100%; 81 | padding: 0; 82 | position: fixed; 83 | top: 44px; 84 | font-size: 0; 85 | z-index: 1; 86 | } 87 | 88 | .carousel .gray-layer { 89 | position: fixed; 90 | top:0; 91 | bottom: 0; 92 | left:0; 93 | right:0; 94 | background: rgba(0,0,0,.2); 95 | z-index: 0 96 | } 97 | 98 | .carousel .magazine-cate { 99 | font-family: PingFangSC-Regular; 100 | font-size: 14px; 101 | color: #4D4D4D; 102 | letter-spacing: 0; 103 | text-align: center; 104 | width: 100%; 105 | background: #F5F5F5; 106 | position: relative; 107 | z-index: 9; 108 | } 109 | 110 | .carousel .magazine-cate-title { 111 | position: relative; 112 | top: 1px; 113 | } 114 | 115 | .carousel .magazine-cate.cur { 116 | background-color: #fff; 117 | } 118 | 119 | .carousel .magazine-cate:after, .carousel .magazine-cate:before { 120 | position: absolute; 121 | content: " "; 122 | left: 0; 123 | right: 0; 124 | height: 1px; 125 | } 126 | 127 | .carousel .magazine-cate:after { 128 | height: 4px; 129 | bottom: -4px; 130 | background-image: -webkit-linear-gradient(90deg, #fff 66.666666%, #ccc 50%); 131 | background-image: linear-gradient(0deg, #fff 66.666666%, #ccc 100%); 132 | } 133 | 134 | .carousel .magazine-cate.cur:after { 135 | display: none; 136 | } 137 | 138 | .carousel .magazine-cate:before { 139 | top: 0; 140 | background-image: -webkit-linear-gradient(90deg, #e0e0e0 50%, transparent 100%); 141 | background-image: linear-gradient(0deg, transparent 50%, #e0e0e0 50%); 142 | } 143 | 144 | .carousel .magazine-cate-cont li { 145 | font-size: 14px; 146 | color: #333333; 147 | letter-spacing: 0; 148 | padding-left: 15px; 149 | background-color: #fff; 150 | height: 50px; 151 | line-height: 50px; 152 | text-align: left; 153 | } 154 | 155 | .carousel .magazine-cate-cont { 156 | position: absolute; 157 | width: 100%; 158 | left: 0; 159 | top: 44px; 160 | height: auto; 161 | padding-bottom: 10px; 162 | transform: translateY(-100%); 163 | -webkit-transform: translateY(-100%); 164 | background-color: #fff; 165 | overflow: hidden; 166 | } 167 | 168 | .carousel .magazine-cate-cont.cur { 169 | transform: translateY(0); 170 | -webkit-transform: translateY(0); 171 | } 172 | 173 | .carousel .magazine-cate-cont:after { 174 | top: 1px; 175 | height: 1px; 176 | } 177 | 178 | .carousel .slide-img { 179 | width: 100%; 180 | height: 300px; 181 | background-size: cover; 182 | } 183 | 184 | .carousel .magazine-slider { 185 | width: 100%; 186 | height: auto; 187 | position: absolute; 188 | top: 50%; 189 | left: 0; 190 | transform: translateY(-43%); 191 | -webkit-transform: translateY(-43%); 192 | } 193 | 194 | /* 比例调试 */ 195 | .carousel .magazine-slider.cur{ 196 | transform: translateY(-46.5%); 197 | -webkit-transform: translateY(-46.5%); 198 | } 199 | 200 | .carousel .magazine-arr-wrap { 201 | display: inline-block; 202 | vertical-align: middle; 203 | width: 15px; 204 | } 205 | 206 | .carousel .magazine-arr-wrap span:first-child { 207 | display: inline-block; 208 | } 209 | 210 | .carousel .magazine-arr-wrap span:last-child { 211 | display: none; 212 | } 213 | 214 | .carousel .magazine-arr-wrap.cur span:first-child { 215 | display: none; 216 | } 217 | 218 | .carousel .magazine-arr-wrap.cur span:last-child { 219 | display: inline-block; 220 | } 221 | 222 | .carousel .loading-bubbles, .carousel .loading-bubbles svg { 223 | width:60px; 224 | height:60px; 225 | fill: #b7b7b7; 226 | } 227 | 228 | .carousel ion-content, .carousel ion-content .scroll { 229 | background: #F5F5F5; 230 | } 231 | 232 | /* 超级大屏幕 */ 233 | @media (min-width: 465px) { 234 | .carousel .slider-wrap-inner img { 235 | height: 4.2rem; 236 | } 237 | } 238 | 239 | @media (min-width: 565px) { 240 | .carousel .slider-wrap-inner img { 241 | height: 5rem; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /src/css/samples.mp3.css: -------------------------------------------------------------------------------- 1 | .audio ion-content { 2 | bottom: 80px; 3 | background-color: #fff; 4 | } 5 | 6 | .play-state { 7 | display: inline-block; 8 | vertical-align: top; 9 | margin: 13px 10px 0 10px; 10 | width: 18px; 11 | height: 18px; 12 | background: url(../images/icon-mp3.png) no-repeat center bottom; 13 | background-size: 100% auto; 14 | } 15 | 16 | .animate-zone { 17 | position: absolute; 18 | width: 2rem; 19 | height: 2rem; 20 | max-width: 300px; 21 | padding: 12px; 22 | background-color: #808080; 23 | border-radius: 50%; 24 | } 25 | 26 | .audio-bottom { 27 | position: fixed; 28 | bottom: 0; 29 | height: 80px; 30 | left: 0; 31 | right: 0; 32 | } 33 | 34 | .audio-time { 35 | padding: 30px 10px 0; 36 | } 37 | 38 | .audio-controll-bar .play-btn { 39 | width: 36px; 40 | height: 36px; 41 | } 42 | 43 | .audio-progress-zone { 44 | position: absolute; 45 | top: -1px; 46 | left: 0; 47 | right: 0; 48 | width: 100%; 49 | height: 0; 50 | } 51 | 52 | .audio-progress-zone .audio-range-input { 53 | width: 100%; 54 | margin: 0; 55 | padding: 0; 56 | border: none; 57 | box-shadow: none; 58 | background: none; 59 | height: 15px; 60 | } 61 | 62 | .audio-controll-bar .playing-btn { 63 | background: url('../images/icon-mp3.png') no-repeat center bottom !important; 64 | background-size: 100% auto !important; 65 | } 66 | 67 | .audio-controll-bar .audio-range-input[type="range"]::-webkit-slider-thumb { 68 | -webkit-appearance: none; 69 | cursor: default; 70 | top: 0; 71 | height: 14px; 72 | width: 14px; 73 | background: #808080; 74 | border-radius: 50%; 75 | box-shadow: 0 0 3px #fff; 76 | overflow: visible; 77 | position: relative; 78 | } 79 | 80 | .audio-controll-bar .audio-range-input[type="range"]::-webkit-slider-thumb:before { 81 | position: absolute; 82 | content: ' '; 83 | top: 5px; 84 | left: -1998px; 85 | background: #808080; 86 | } 87 | 88 | .audio-controll-bar .audio-range-track { 89 | width: 100%; 90 | height: 2px; 91 | background-color: #d2d2d2; 92 | } 93 | 94 | .audio-controll-bar .play-btn.cur .playing-btn { 95 | background-position: center 0 !important; 96 | } 97 | 98 | .animate-zone-inner { 99 | position: absolute; 100 | top: 12px; 101 | left: 12px; 102 | right: 12px; 103 | bottom: 12px; 104 | border-radius: 50%; 105 | font-size: 30px; 106 | background-color: #fdfdfd; 107 | color: #808080; 108 | animation: audioRotate 5s linear infinite; 109 | -webkit-animation: audioRotate 5s linear infinite; 110 | animation-play-state: paused; 111 | -webkit-animation-play-state: paused; 112 | } 113 | 114 | .animate-zone-inner.cur { 115 | animation-play-state: running; 116 | -webkit-animation-play-state: running; 117 | } 118 | 119 | @keyframes audioRotate { 120 | from { 121 | transform: rotate(0deg); 122 | } 123 | to { 124 | transform: rotate(360deg); 125 | } 126 | } 127 | 128 | @-webkit-keyframes audioRotate { 129 | from { 130 | -webkit-transform: rotate(0deg); 131 | } 132 | to { 133 | -webkit-transform: rotate(360deg); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/css/samples.pdf.css: -------------------------------------------------------------------------------- 1 | .pdf ion-content .scroll { 2 | height: 100%; 3 | } 4 | -------------------------------------------------------------------------------- /src/css/samples.video.css: -------------------------------------------------------------------------------- 1 | .video ion-content { 2 | margin-top: -44px; 3 | } 4 | 5 | .video .scroll { 6 | overflow: hidden; 7 | } 8 | 9 | .video-container, 10 | .video-container video { 11 | width: 100%; 12 | height: 100%; 13 | background: #000; 14 | } 15 | 16 | .video-controll-bar { 17 | position: fixed; 18 | bottom: 0; 19 | width: 100%; 20 | height: 56px; 21 | line-height: 56px; 22 | background-color: rgba(0, 0, 0, .3); 23 | transition: all .2s ease-out 0s; 24 | -webkit-transition: all .2s ease-out 0s; 25 | } 26 | 27 | .video-time { 28 | margin-left: 10px; 29 | font-size: 13px; 30 | color: #fff; 31 | } 32 | 33 | .play-btn { 34 | width: 56px; 35 | height: 56px; 36 | } 37 | 38 | .playing-btn { 39 | display: block; 40 | width: 100%; 41 | height: 100%; 42 | background: url(../images/play-btn.png) no-repeat center -23px; 43 | background-size: 45% auto; 44 | } 45 | 46 | .play-btn.cur .playing-btn { 47 | background-position: center 18px; 48 | background-size: 50% auto; 49 | } 50 | 51 | .video-progress-zone .video-range-input { 52 | width: 100%; 53 | margin: 0; 54 | padding: 0; 55 | border: none; 56 | box-shadow: none; 57 | background: none; 58 | height: 15px; 59 | } 60 | 61 | .video-progress-zone .video-range-track { 62 | width: 100%; 63 | height: 3px; 64 | background-color: rgba(255, 255, 255, .3); 65 | } 66 | 67 | .video-progress-zone { 68 | position: absolute; 69 | top: -1px; 70 | left: 0; 71 | right: 0; 72 | width: 100%; 73 | height: 0; 74 | } 75 | 76 | .video-controll-bar .video-range-input[type="range"]::-webkit-slider-thumb { 77 | -webkit-appearance: none; 78 | cursor: default; 79 | top: 0; 80 | height: 12px; 81 | width: 12px; 82 | background: #fff; 83 | border-radius: 50%; 84 | box-shadow: 0 0 3px #fff; 85 | overflow: visible; 86 | position: relative; 87 | } 88 | 89 | .video-controll-bar .video-range-input[type="range"]::-webkit-slider-thumb:before { 90 | position: absolute; 91 | content: ' '; 92 | top: 5px; 93 | left: -1998px; 94 | background: #fff; 95 | } 96 | 97 | .video-container .spinner { 98 | fill: #808080; 99 | } 100 | 101 | .video-container .spinner svg { 102 | width: 70px; 103 | height: 70px; 104 | } 105 | 106 | 107 | /* 隐藏bar的动画 */ 108 | 109 | .video.cur .video-controll-bar { 110 | transform: translate3d(0, 62px, 0); 111 | -webkit-transform: translate3d(0, 62px, 0); 112 | } 113 | 114 | .video.cur ion-header-bar { 115 | transform: translate3d(0, -44px, 0); 116 | -webkit-transform: translate3d(0, -44px, 0); 117 | } 118 | -------------------------------------------------------------------------------- /src/css/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | article, 4 | aside, 5 | audio, 6 | canvas, 7 | caption, 8 | details, 9 | div, 10 | figure, 11 | footer, 12 | header, 13 | iframe, 14 | img, 15 | mark, 16 | menu, 17 | nav, 18 | object, 19 | section, 20 | span, 21 | summary, 22 | table, 23 | tbody, 24 | td, 25 | tfoot, 26 | thead, 27 | tr, 28 | video, 29 | a, 30 | button, 31 | b, 32 | u, 33 | i, 34 | ins, 35 | em, 36 | ol, 37 | ul, 38 | li, 39 | ::before, 40 | ::after { 41 | padding: 0; 42 | margin: 0; 43 | border: none; 44 | font-style: normal; 45 | -webkit-tap-highlight-color: transparent; 46 | -webkit-box-sizing: border-box; 47 | box-sizing: border-box; 48 | -webkit-touch-callout: none; 49 | -webkit-user-select: none; 50 | -webkit-text-size-adjust: 100%; 51 | } 52 | 53 | html, 54 | body { 55 | background-color: #fff; 56 | } 57 | 58 | body { 59 | font-size: .12rem; 60 | font-family: "Droid Sans", "Droid Sans Fallback", PingFangSC-Regular, Helvetica-Neue, Helvetica, Arial, sans-serif; 61 | color: #666; 62 | } 63 | 64 | ol, 65 | ul { 66 | list-style: none; 67 | } 68 | 69 | h1, 70 | h2, 71 | h3, 72 | h4, 73 | h5, 74 | h6 { 75 | font-weight: normal; 76 | margin: 0; 77 | } 78 | 79 | a { 80 | text-decoration: none; 81 | color: #666; 82 | } 83 | 84 | input, 85 | textarea { 86 | border: 0; 87 | resize: none; 88 | outline: none; 89 | -webkit-appearance: none; 90 | } 91 | 92 | button { 93 | outline: none; 94 | } 95 | 96 | .clearfix::before, 97 | .clearfix::after { 98 | content: ' '; 99 | display: block; 100 | height: 0; 101 | line-height: 0; 102 | visibility: hidden; 103 | clear: both; 104 | } 105 | 106 | .ellipsis { 107 | overflow: hidden; 108 | white-space: nowrap; 109 | text-overflow: ellipsis; 110 | } 111 | 112 | .ellipsis-two { 113 | display: -webkit-box !important; 114 | overflow: hidden !important; 115 | text-overflow: ellipsis !important; 116 | -webkit-line-clamp: 2 !important; 117 | -webkit-box-orient: vertical !important; 118 | white-space: normal !important; 119 | } 120 | 121 | .text-indent { 122 | text-indent: 2em; 123 | } 124 | 125 | .pull-left { 126 | float: left; 127 | } 128 | 129 | .pull-right { 130 | float: right; 131 | } 132 | 133 | :focus { 134 | outline: 0 135 | } 136 | 137 | html { 138 | font-size: 100px; 139 | } 140 | 141 | @media (min-width: 320px) { 142 | html { 143 | font-size: 100px; 144 | } 145 | } 146 | 147 | @media (min-width: 360px) { 148 | html { 149 | font-size: 112.5px; 150 | } 151 | } 152 | 153 | @media (min-width: 400px) { 154 | html { 155 | font-size: 125px; 156 | } 157 | } 158 | 159 | 160 | /* 0.5px线条 */ 161 | 162 | .bd-l, 163 | .bd-r, 164 | .bd-b, 165 | .bd-t, 166 | .bd-all { 167 | position: relative; 168 | } 169 | 170 | .bd-l::after { 171 | content: ' '; 172 | position: absolute; 173 | top: 0; 174 | left: 0; 175 | width: 1px; 176 | height: 100%; 177 | background-image: -webkit-linear-gradient(270deg, #e0e0e0 50%, transparent 50%); 178 | background-image: linear-gradient(180deg, #e0e0e0 50%, transparent 50%); 179 | } 180 | 181 | .bd-r::after { 182 | content: ' '; 183 | position: absolute; 184 | top: 0; 185 | right: 0; 186 | width: 1px; 187 | height: 100%; 188 | background-image: -webkit-linear-gradient(180deg, #e0e0e0 50%, transparent 50%); 189 | background-image: linear-gradient(270deg, #e0e0e0 50%, transparent 50%); 190 | } 191 | 192 | .bd-t::after { 193 | content: " "; 194 | position: absolute; 195 | left: 0; 196 | top: 0; 197 | right: 0; 198 | height: 1px; 199 | border-top: 1px solid #e0e0e0; 200 | -webkit-transform-origin: 0 0; 201 | transform-origin: 0 0; 202 | -webkit-transform: scaleY(0.5); 203 | transform: scaleY(0.5); 204 | } 205 | 206 | .bd-b::after { 207 | content: " "; 208 | position: absolute; 209 | left: 0; 210 | bottom: 0; 211 | right: 0; 212 | height: 1px; 213 | border-top: 1px solid #e0e0e0; 214 | -webkit-transform-origin: 0 0; 215 | transform-origin: 0 0; 216 | -webkit-transform: scaleY(0.5); 217 | transform: scaleY(0.5); 218 | } 219 | 220 | .bd-all::after { 221 | content: ' '; 222 | width: 200%; 223 | height: 200%; 224 | position: absolute; 225 | left: 0; 226 | top: 0; 227 | border: 1px solid #d3d3d3; 228 | transform-origin: 0 0; 229 | -webkit-transform-origin: 0 0; 230 | transform: scale(.5, .5); 231 | -webkit-transform: scale(.5, .5); 232 | } 233 | 234 | 235 | /* 竖向居中 */ 236 | 237 | .vertical-center { 238 | position: absolute; 239 | top: 50%; 240 | transform: translateY(-50%); 241 | -webkit-transform: translateY(-50%); 242 | } 243 | 244 | 245 | /* 横向居中 */ 246 | 247 | .horizontal-center { 248 | position: absolute; 249 | left: 50%; 250 | transform: translateX(-50%); 251 | -webkit-transform: translateX(-50%); 252 | } 253 | 254 | 255 | /* 横竖居中 */ 256 | 257 | .center-center { 258 | position: absolute; 259 | left: 50%; 260 | top: 50%; 261 | transform: translateX(-50%) translateY(-50%); 262 | -webkit-transform: translateX(-50%) translateY(-50%); 263 | } 264 | 265 | 266 | /* 左右margin 10 */ 267 | 268 | .mlr10 { 269 | margin: 0 10px 0 10px; 270 | } 271 | 272 | 273 | /* 高度100% 百分数用_ px不用_ */ 274 | 275 | .h_100 { 276 | height: 100%; 277 | } 278 | 279 | .f-10 { 280 | font-size: 10px !important; 281 | } 282 | 283 | .f-12 { 284 | font-size: 12px !important; 285 | } 286 | 287 | .f-13 { 288 | font-size: 13px !important; 289 | } 290 | 291 | .f-14 { 292 | font-size: 14px !important; 293 | } 294 | 295 | .c-888 { 296 | color: #888 !important; 297 | } 298 | 299 | .c-999 { 300 | color: #999 !important; 301 | } 302 | 303 | .c-666 { 304 | color: #666 !important; 305 | } 306 | 307 | .c-333 { 308 | color: #333 !important; 309 | } 310 | 311 | .f-border { 312 | font-weight: 500 !important; 313 | font-size: 13px; 314 | } 315 | 316 | .f-normal { 317 | font-weight: normal !important; 318 | } 319 | 320 | 321 | /* 头部公用样式 */ 322 | 323 | 324 | /* ionic 过渡时的突然消失的bug */ 325 | 326 | ion-nav-bar.hide { 327 | display: block !important; 328 | } 329 | 330 | 331 | /* 去除默认样式 */ 332 | 333 | 334 | /* 去除默认样式 */ 335 | 336 | ion-nav-bar ion-header-bar { 337 | padding-left: 0; 338 | padding-right: 0; 339 | } 340 | 341 | .header-search { 342 | height: 100%; 343 | position: relative; 344 | } 345 | 346 | .header-search.cur { 347 | margin-right: 36px; 348 | } 349 | 350 | .header-search.cur ~ .cancel-search { 351 | font-size: 16px; 352 | opacity: 1; 353 | } 354 | 355 | .header-search .header-search-inner { 356 | height: 30px; 357 | line-height: 30px; 358 | background-color: #dadada; 359 | border-radius: 5px; 360 | width: 100%; 361 | text-align: left; 362 | } 363 | 364 | .header-search .header-search-inner:before { 365 | position: absolute; 366 | content: ' '; 367 | } 368 | 369 | ion-header-bar .search-icon-right { 370 | width: 20px; 371 | height: 20px; 372 | margin-right: 8px; 373 | } 374 | 375 | .header-search .search-input { 376 | position: absolute; 377 | width: 100% !important; 378 | height: 100% !important; 379 | border: none !important; 380 | padding: 0 0 0 27px !important; 381 | font-size: 14px; 382 | top: 0; 383 | color: #fff; 384 | background-color: transparent; 385 | } 386 | 387 | .header-search .search-input::-webkit-input-placeholder { 388 | color: #fff; 389 | } 390 | 391 | .header-search-wrap { 392 | height: 44px; 393 | background-color: #808080; 394 | } 395 | 396 | .header-search-wrap .cancel-search { 397 | position: absolute; 398 | top: 0; 399 | right: 6px; 400 | line-height: 45px; 401 | font-size: 12px; 402 | opacity: 0; 403 | color: #fff; 404 | } 405 | 406 | .header-search .clear-btn.cur { 407 | display: block; 408 | } 409 | 410 | ion-header-bar .btn-right { 411 | color: #fff !important; 412 | margin-right: 5px; 413 | } 414 | 415 | ion-header-bar .btn-left { 416 | margin-left: 5px; 417 | } 418 | 419 | 420 | /* 设置按钮 */ 421 | 422 | .ion-gear-b { 423 | font-size: 26px; 424 | color: #fff; 425 | } 426 | 427 | 428 | /* lessonList 列表 通用 */ 429 | 430 | .list.course-list .cli-footer { 431 | position: absolute; 432 | left: 108px; 433 | right: 16px; 434 | bottom: 5px; 435 | } 436 | 437 | .course-list h2.ellipsis-two { 438 | line-height: 24px; 439 | height: 48px; 440 | } 441 | 442 | ion-item.item { 443 | border: none; 444 | margin: 0; 445 | padding: 5px 0; 446 | } 447 | 448 | ion-item:after { 449 | z-index: 10; 450 | } 451 | 452 | .course-list img, 453 | .lazy img { 454 | background-color: #f2f2f2; 455 | background-size: cover; 456 | background-position: center center; 457 | background-repeat: no-repeat; 458 | } 459 | 460 | 461 | /* 去除ion-item 点击后背景变灰 */ 462 | 463 | .item.active, 464 | .item.activated, 465 | .item-complex.active .item-content, 466 | .item-complex.activated .item-content, 467 | .item .item-content.active, 468 | .item .item-content.activated, 469 | .item.active.item-complex > .item-content, 470 | .item.activated.item-complex > .item-content, 471 | .item-complex.active .item-content.item-complex > .item-content, 472 | .item-complex.activated .item-content.item-complex > .item-content, 473 | .item .item-content.active.item-complex > .item-content, 474 | .item .item-content.activated.item-complex > .item-content { 475 | border-color: transparent; 476 | background-color: transparent; 477 | } 478 | 479 | 480 | /* 通用返回按钮 */ 481 | 482 | ion-header-bar .go-back { 483 | color: #fff !important; 484 | padding-left: 22px !important; 485 | } 486 | 487 | .common-back-btn { 488 | padding: 0 10px 0 8px; 489 | z-index: 9999; 490 | } 491 | 492 | /* 覆盖一些默认样式 */ 493 | 494 | [nav-view-transition="ios"][nav-view-direction="forward"], 495 | [nav-view-transition="ios"][nav-view-direction="back"] { 496 | background-color: transparent; 497 | } 498 | 499 | 500 | /* ionic 转场中的bug 弥补 */ 501 | 502 | ion-nav-bar.hide { 503 | display: block !important; 504 | } 505 | 506 | 507 | /* 解决多个input 在手机上无法ng-submit 提交的问题 [不能使用display:none] */ 508 | 509 | .multi-input-submit { 510 | position: absolute; 511 | top: -1000%; 512 | left: 0; 513 | opacity: 0; 514 | z-index: -1; 515 | } 516 | 517 | 518 | /* 弹性盒 */ 519 | 520 | .mui-flex { 521 | display: -webkit-box; 522 | display: -ms-flexbox; 523 | display: -moz-box; 524 | display: -webkit-flex; 525 | display: flex; 526 | } 527 | 528 | .flex { 529 | -webkit-box-flex: 1; 530 | -moz-box-flex: 1; 531 | -webkit-flex: 1; 532 | -ms-flex: 1; 533 | flex: 1; 534 | } 535 | 536 | 537 | /* track 样式重置 */ 538 | 539 | .toggle .track { 540 | border-width: 1px; 541 | } 542 | 543 | .not-found img { 544 | padding-top: 50px; 545 | width: 70px; 546 | background: transparent; 547 | } 548 | 549 | .not-found div { 550 | line-height: 45px; 551 | font-size: 14px; 552 | color: #888; 553 | } 554 | 555 | 556 | /* tab 栏bug弥补 */ 557 | 558 | .tab-item { 559 | max-width: none; 560 | } 561 | 562 | 563 | /* modal样式的覆盖 */ 564 | 565 | .modal { 566 | top: 0; 567 | right: 0; 568 | bottom: 0; 569 | left: 0; 570 | min-height: 240px; 571 | } 572 | 573 | .no-scroll-bar::-webkit-scrollbar, 574 | .no-scroll-bar .scroll::-webkit-scrollbar { 575 | display: none; 576 | } 577 | 578 | ion-header-bar.bar .title { 579 | box-sizing: border-box; 580 | white-space: nowrap; 581 | overflow: hidden; 582 | text-overflow: ellipsis; 583 | font-weight: 400; 584 | } 585 | 586 | [nav-bar-transition="ios"] .title, 587 | [nav-bar-transition="ios"] .buttons, 588 | [nav-bar-transition="ios"] .back-text, 589 | [nav-bar-transition="android"] .title, 590 | [nav-bar-transition="android"] .buttons { 591 | -webkit-transition-duration: 0ms; 592 | transition-duration: 0ms; 593 | } 594 | 595 | .no-wrap { 596 | white-space: nowrap; 597 | overflow: hidden; 598 | text-overflow: ellipsis; 599 | } 600 | 601 | .tabs { 602 | border: none; 603 | } 604 | 605 | .outer-pages .load-progress { 606 | width: 0; 607 | height: 2px; 608 | position: absolute; 609 | z-index: 999999; 610 | top: 0; 611 | background-color: #00b100; 612 | transition: width 3s ease 0s; 613 | -webkit-transition: width 3s ease 0s; 614 | } 615 | 616 | .outer-pages iframe { 617 | position: absolute; 618 | width: 100%; 619 | height: 100%; 620 | top: 0; 621 | } 622 | -------------------------------------------------------------------------------- /src/data/bio-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/biol01.jpg", 4 | "title": "农业生物技术", 5 | "magCode": "BIOL" 6 | }, 7 | { 8 | "coverimg": "images/carousel/biol02.jpg", 9 | "title": "生物能源技术", 10 | "magCode": "BIOL" 11 | }, 12 | { 13 | "coverimg": "images/carousel/biol03.jpg", 14 | "title": "特色农业生物技术", 15 | "magCode": "BIOL" 16 | }, 17 | { 18 | "coverimg": "images/carousel/biol04.jpg", 19 | "title": "基因组育种", 20 | "magCode": "BIOL" 21 | }, 22 | { 23 | "coverimg": "images/carousel/biol05.jpg", 24 | "title": "食品生物技术", 25 | "magCode": "BIOL" 26 | } 27 | ] -------------------------------------------------------------------------------- /src/data/com-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/comp01.jpg", 4 | "title": "计算语言学", 5 | "magCode": "COMP" 6 | }, 7 | { 8 | "coverimg": "images/carousel/comp02.jpg", 9 | "title": "机器学习", 10 | "magCode": "COMP" 11 | }, 12 | { 13 | "coverimg": "images/carousel/comp03.jpg", 14 | "title": "云计算", 15 | "magCode": "COMP" 16 | }, 17 | { 18 | "coverimg": "images/carousel/comp04.jpg", 19 | "title": "互联网创新应用", 20 | "magCode": "COMP" 21 | }, 22 | { 23 | "coverimg": "images/carousel/comp05.jpg", 24 | "title": "移动计算", 25 | "magCode": "COMP" 26 | } 27 | ] -------------------------------------------------------------------------------- /src/data/eco-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/econ01.jpg", 4 | "title": "经济增长", 5 | "magCode": "ECON" 6 | }, 7 | { 8 | "coverimg": "images/carousel/econ02.jpg", 9 | "title": "绿色经济", 10 | "magCode": "ECON" 11 | }, 12 | { 13 | "coverimg": "images/carousel/econ03.jpg", 14 | "title": "网络经济", 15 | "magCode": "ECON" 16 | }, 17 | { 18 | "coverimg": "images/carousel/econ04.jpg", 19 | "title": "蓝海战略", 20 | "magCode": "ECON" 21 | }, 22 | { 23 | "coverimg": "images/carousel/econ05.jpg", 24 | "title": "电子商务市场", 25 | "magCode": "ECON" 26 | } 27 | ] -------------------------------------------------------------------------------- /src/data/latest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/latest01.jpg", 4 | "title": "民间文学", 5 | "magCode": "LITE" 6 | }, 7 | { 8 | "coverimg": "images/carousel/latest02.jpg", 9 | "title": "视觉传播", 10 | "magCode": "COAR" 11 | }, 12 | { 13 | "coverimg": "images/carousel/latest03.jpg", 14 | "title": "光量子器件及通信", 15 | "magCode": "COMM" 16 | }, 17 | { 18 | "coverimg": "images/carousel/latest04.jpg", 19 | "title": "营养管理", 20 | "magCode": "FOOD" 21 | }, 22 | { 23 | "coverimg": "images/carousel/latest05.jpg", 24 | "title": "晶体材料", 25 | "magCode": "MATE" 26 | } 27 | ] -------------------------------------------------------------------------------- /src/data/mag-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "magName": "经济学", 4 | "magCode": "ECON" 5 | }, 6 | { 7 | "magName": "生物技术", 8 | "magCode": "BIOL" 9 | }, 10 | { 11 | "magName": "计算机科技", 12 | "magCode": "COMP" 13 | } 14 | ] -------------------------------------------------------------------------------- /src/images/adam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/adam.jpg -------------------------------------------------------------------------------- /src/images/ben.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/ben.png -------------------------------------------------------------------------------- /src/images/bg-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/bg-book.png -------------------------------------------------------------------------------- /src/images/carousel/biol01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/biol01.jpg -------------------------------------------------------------------------------- /src/images/carousel/biol02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/biol02.jpg -------------------------------------------------------------------------------- /src/images/carousel/biol03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/biol03.jpg -------------------------------------------------------------------------------- /src/images/carousel/biol04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/biol04.jpg -------------------------------------------------------------------------------- /src/images/carousel/biol05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/biol05.jpg -------------------------------------------------------------------------------- /src/images/carousel/comp01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/comp01.jpg -------------------------------------------------------------------------------- /src/images/carousel/comp02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/comp02.jpg -------------------------------------------------------------------------------- /src/images/carousel/comp03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/comp03.jpg -------------------------------------------------------------------------------- /src/images/carousel/comp04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/comp04.jpg -------------------------------------------------------------------------------- /src/images/carousel/comp05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/comp05.jpg -------------------------------------------------------------------------------- /src/images/carousel/econ01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/econ01.jpg -------------------------------------------------------------------------------- /src/images/carousel/econ02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/econ02.jpg -------------------------------------------------------------------------------- /src/images/carousel/econ03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/econ03.jpg -------------------------------------------------------------------------------- /src/images/carousel/econ04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/econ04.jpg -------------------------------------------------------------------------------- /src/images/carousel/econ05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/econ05.jpg -------------------------------------------------------------------------------- /src/images/carousel/latest01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/latest01.jpg -------------------------------------------------------------------------------- /src/images/carousel/latest02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/latest02.jpg -------------------------------------------------------------------------------- /src/images/carousel/latest03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/latest03.jpg -------------------------------------------------------------------------------- /src/images/carousel/latest04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/latest04.jpg -------------------------------------------------------------------------------- /src/images/carousel/latest05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/carousel/latest05.jpg -------------------------------------------------------------------------------- /src/images/icon-mp3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/icon-mp3.png -------------------------------------------------------------------------------- /src/images/ionic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/ionic.png -------------------------------------------------------------------------------- /src/images/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/max.png -------------------------------------------------------------------------------- /src/images/mike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/mike.png -------------------------------------------------------------------------------- /src/images/perry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/perry.png -------------------------------------------------------------------------------- /src/images/play-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/play-btn.png -------------------------------------------------------------------------------- /src/images/post-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/post-bg.gif -------------------------------------------------------------------------------- /src/images/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/images/transparent.gif -------------------------------------------------------------------------------- /src/index.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 | 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 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/js/app.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples', [ 2 | 'ionic', 3 | 'ionic-native-transitions', 4 | 'ngCordova', 5 | 'ngCookies', 6 | 'templates' 7 | ]) 8 | .run(function($ionicPlatform) { 9 | $ionicPlatform.ready(function() { 10 | if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) { 11 | cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 12 | cordova.plugins.Keyboard.disableScroll(true); 13 | } 14 | if (window.StatusBar) { 15 | // org.apache.cordova.statusbar required 16 | StatusBar.styleDefault(); 17 | } 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/js/app.templates.js: -------------------------------------------------------------------------------- 1 | // THIS IS A PLACEHOLDER, TO BE REPLACED DURING PRODUCTION BUILDS BY GULP-ANGULAR-TEMPLATECACHE - DO NOT REMOVE ! 2 | angular.module("templates", []); 3 | -------------------------------------------------------------------------------- /src/js/config.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | // 配置模块,控制不同平台的兼容性 3 | angular.module('ionic-samples') 4 | .config(function($urlRouterProvider, $httpProvider, $ionicConfigProvider) { 5 | $urlRouterProvider.otherwise('/tab/dash'); // 默认路由 6 | // $httpProvider.interceptors.push('authInterceptor'); // 设置拦截器 7 | ionic.Platform.isFullScreen = false; // 禁止全屏显示 8 | 9 | $ionicConfigProvider.views.maxCache(15); 10 | $ionicConfigProvider.views.transition('platform'); 11 | $ionicConfigProvider.views.forwardCache(true); // 缓存下一页 12 | $ionicConfigProvider.views.swipeBackEnabled(ionic.Platform.isIOS()); 13 | $ionicConfigProvider.spinner.icon('ios'); 14 | 15 | // 通用样式的兼容 16 | $ionicConfigProvider.platform.android.tabs.position("bottom"); 17 | $ionicConfigProvider.platform.ios.tabs.position("bottom"); 18 | $ionicConfigProvider.platform.ios.navBar.alignTitle('center'); 19 | $ionicConfigProvider.platform.android.navBar.alignTitle('center'); 20 | $ionicConfigProvider.platform.ios.backButton.previousTitleText('').icon('ion-ios-arrow-left'); 21 | $ionicConfigProvider.platform.android.backButton.previousTitleText('').icon('ion-ios-arrow-left'); 22 | $ionicConfigProvider.tabs.style('standard'); 23 | // false 默认所有的滚动使用native,会比js的滚动快很多,并且很平滑 ; 安卓使用,ios不使用 24 | $ionicConfigProvider.scrolling.jsScrolling(!ionic.Platform.isAndroid()); 25 | }) 26 | })(angular); 27 | -------------------------------------------------------------------------------- /src/js/directives.js: -------------------------------------------------------------------------------- 1 | /* 此处的指令是通用的指令 */ 2 | (function(angular) { 3 | 'use strict'; 4 | angular.module('ionic-samples') 5 | /* 自动获取焦点 */ 6 | .directive('autoFocus', function($timeout, $cordovaKeyboard) { 7 | return { 8 | restrict: 'A', 9 | link: function(scope, element) { 10 | $timeout(function() { 11 | if (!window.cordova) return; 12 | $cordovaKeyboard.show(); 13 | element[0].focus(); 14 | }, 600); 15 | } 16 | }; 17 | }) 18 | /* 通用iframe 加载进度条 */ 19 | .directive('iframeLoad', function($timeout) { 20 | return { 21 | restrict: 'A', 22 | link: function(scope, element) { 23 | var ele = element[0]; 24 | var theFrame = element.next()[0]; 25 | ele.style.width = '90%'; // iframe 不提供进度接口, 解决方案: 执行一个动画,首先加载到90% 26 | // 定义一个获取dom的方法并隐藏的方法 27 | var hide = function(context, obj) { 28 | if (Array.isArray(obj)) { 29 | obj.forEach(function(item) { 30 | context.contentWindow.document.getElementById(item).style.display = 'none'; // 隐藏按钮 31 | }); 32 | } else { 33 | context.contentWindow.document.getElementById(obj).style.display = 'none'; // 隐藏按钮 34 | } 35 | }; 36 | theFrame.addEventListener('load', function(e) { 37 | if (!e) { 38 | return ele.style.display = 'none'; 39 | } 40 | // 进度条走完并且消失 41 | ele.style.width = '100%'; 42 | $timeout(function() { 43 | ele.style.display = 'none'; 44 | // 浏览器有跨域问题, 客户端正常 45 | if (window.cordova) { 46 | var arr = ['secondaryOpenFile', 'secondaryPrint', 'secondaryDownload', 'secondaryViewBookmark', 'toggleHandTool']; 47 | hide(theFrame, arr); 48 | } 49 | }, 600); 50 | }, false); 51 | } 52 | }; 53 | }) 54 | })(angular); 55 | -------------------------------------------------------------------------------- /src/js/global.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | angular.module('ionic-samples') 4 | .constant("global", { 5 | apiUrl: function() { 6 | if (window.cordova) { 7 | return { 8 | 9 | } 10 | } else { 11 | var port = window.location.port; 12 | return { 13 | 14 | } 15 | } 16 | }, 17 | dataUrl: 'https://raw.githubusercontent.com/johnnynode/ionic-samples/ionic-v1/src/data', 18 | mediaUrl: 'https://raw.githubusercontent.com/johnnynode/ionic-samples/ionic-v1/src/media' 19 | }) 20 | })(angular); -------------------------------------------------------------------------------- /src/js/mobile-move.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | var MobileMove = function () { 3 | }; 4 | MobileMove.prototype = { 5 | addTransition: function (obj, time) { 6 | obj.style.transition = "all " + time + "s ease"; 7 | obj.style.webkitTransition = "all " + time + "s ease"; 8 | }, 9 | removeTransition: function (obj) { 10 | obj.style.transition = "none"; 11 | obj.style.webkitTransition = "none"; 12 | }, 13 | changeTranslateX: function (obj, x) { 14 | obj.style.transform = "translateX(" + x + "px)"; 15 | obj.style.webkitTransform = "translateX(" + x + "px)"; 16 | }, 17 | transitionEnd: function (obj, callback) { 18 | /*当是对象的时候绑定事件*/ 19 | if (typeof obj === 'object') { 20 | obj.addEventListener('transitionEnd', function (e) { 21 | callback && callback(e); 22 | }, false); 23 | obj.addEventListener('webkitTransitionEnd', function (e) { 24 | callback && callback(e); 25 | }, false); 26 | } 27 | }, 28 | /* 模仿的tap事件 */ 29 | tap: function (obj, callback) { 30 | /* 点击事件 超过200ms */ 31 | if (typeof obj !== 'object') return false; 32 | var startTime = 0, 33 | isMove = false; // 来标记我们是否移动过 34 | obj.addEventListener('touchstart', function () { 35 | startTime = Date.now(); // 取当前时间 36 | }, false); 37 | obj.addEventListener('touchmove', function () { 38 | isMove = true; 39 | }, false); 40 | window.addEventListener('touchend', function (e) { 41 | /* 响应时间小于200ms 并且没有滑动过 */ 42 | if (Date.now() - startTime < 200 && !isMove) { 43 | callback && callback.apply(obj, e); 44 | } 45 | startTime = 0; 46 | isMove = false; 47 | }, false); 48 | }, 49 | /* 缩放动画 */ 50 | scale: function (obj, rate) { 51 | if (!obj) return; 52 | obj.style.transform = "scale(" + rate + ")"; 53 | obj.style.webkitTransform = "scale(" + rate + ")"; 54 | }, 55 | /* 缩放动画的还原 */ 56 | scaleBack: function (obj,index) { 57 | var that = this; 58 | if (!obj) return; 59 | for(var i=0;i 0 滑动方向 true => 左滑 无需考虑 0 97 | _distanceX = distanceX > 0 && distanceX > width ? width : distanceX; // 移动距离>宽度时 ? 移动距离=宽度 98 | _distanceX = !(distanceX > 0) && distanceX < -width ? -width : distanceX; // 移动距离<-宽度时 ? 移动距离=-宽度 99 | var rate = Math.abs(_distanceX / width); // 缩放比率 100 | 101 | if (!(distanceX > 0) && !index || distanceX > 0 && index === num - 1) { 102 | // DO NOTHING 此处做过滤 103 | } else { 104 | if (distanceX > 0) { 105 | // 左滑时缩放 106 | that.scale(imgs[index], 1 - (1 - 252 / 291) * rate); // 当前的缩小 252/291 或者 344/382 这个是缩放比 107 | that.scale(imgs[index + 1], (252 / 291 + (1 - 252 / 291) * rate) <1 ? (252 / 291 + (1 - 252 / 291) * rate) : 1); // 下一个放大 108 | } else { 109 | // 右滑时缩放 110 | that.scale(imgs[index], 1 - (1 - 252 / 291) * rate); // 当前的缩小 111 | that.scale(imgs[index - 1], 252 / 291 + (1 - 252 / 291) * rate); // 上一个放大 112 | } 113 | } 114 | that.removeTransition(obj_move); // 去除过渡 115 | that.changeTranslateX(obj_move, -index * width - distanceX); // 同步盒子移动 116 | }, false); 117 | obj.addEventListener('touchend', function (e) { 118 | e.preventDefault(); 119 | // 移动结束还原缩放 120 | if (!(distanceX > 0) && !index || distanceX > 0 && index === num - 1) { 121 | that.scale(imgs[index], 1); 122 | } 123 | /* 满足1/3的时候滑动一次 */ 124 | if (Math.abs(distanceX) > 1 / 3 * width && endX) { 125 | // 进行 index 加工过滤 126 | index = distanceX > 0 ? ++index : --index; // 根据方向判断中间值 127 | index = index <= 0 ? 0 : index; // 判断第一个时 128 | index = index >= num - 1 ? num - 1 : index; // 判断最后一个时 129 | that.addTransition(obj_move, 0.2); // 加上过渡效果 130 | that.changeTranslateX(obj_move, -index * width); // 滑动 131 | } else { 132 | // 当不满足1/3的时候吸附回去 133 | that.addTransition(obj_move, 0.2); // 加上过渡效果 134 | that.changeTranslateX(obj_move, -index * width); 135 | } 136 | that.scaleBack(imgs,index); // 恢复原始缩放比 137 | 138 | // 每次滑动结束 , 恢复初始值 139 | startX = 0; 140 | endX = 0; 141 | distanceX = 0; 142 | }, false); 143 | } 144 | }; 145 | // 暴露对象 146 | window.MobileMove = MobileMove; 147 | })(window); 148 | -------------------------------------------------------------------------------- /src/js/utils.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | // 配置模块,控制不同平台的兼容性 3 | angular.module('ionic-samples') 4 | .factory('appUtils', [ 5 | '$state', 6 | '$ionicViewSwitcher', 7 | '$ionicNativeTransitions', 8 | '$ionicHistory', 9 | '$cookies', 10 | '$ionicModal', 11 | '$cordovaInAppBrowser', 12 | '$cordovaToast', 13 | '$cordovaKeyboard', 14 | '$ionicScrollDelegate', 15 | function($state, $ionicViewSwitcher, $ionicNativeTransitions, $ionicHistory, $cookies, $ionicModal, 16 | $cordovaInAppBrowser, $cordovaToast, $cordovaKeyboard, $ionicScrollDelegate) { 17 | /* util 构造函数 */ 18 | var Util = function() {}; 19 | 20 | /* util 原型对象 */ 21 | Util.prototype = { 22 | /* 通用返回函数 */ 23 | back: function() { 24 | // 不同平台分别处理,此处使用了ionic-native-transitions插件 25 | $ionicViewSwitcher.nextDirection('back'); 26 | ionic.Platform.isIOS() ? $ionicHistory.goBack() : $ionicNativeTransitions.goBack(); 27 | }, 28 | 29 | /* 进入某个路由模块 */ 30 | /* 路由的跳转不推荐使用a标签加上相应属性来做,用事件和下面的方法来跳转有效果较好的转场动画 */ 31 | go: function(route, params, callback) { 32 | $ionicViewSwitcher.nextDirection('forward'); 33 | $state.go(route, params); 34 | callback && typeof callback === 'function' && callback(); 35 | }, 36 | 37 | /* 解决双平台刷新问题的直接进入 tab栏 on-select 时使用 直接进入模块(无动画) */ 38 | doGo: function(url) { 39 | $ionicNativeTransitions.locationUrl(url, { 40 | "type": "fade", 41 | "duration": 0 42 | }); 43 | }, 44 | 45 | /* 字符串 trim 函数 */ 46 | trim: function(str) { 47 | if (typeof str === 'string') { 48 | return str.replace(/^\s+|\s+$/g, ""); 49 | } 50 | }, 51 | 52 | /* 截取字符串的方法 */ 53 | textCut: function(str, num) { 54 | if (typeof str === 'string' && typeof num === 'number' && str.length >= num) { 55 | var temp = str.slice(0, num); 56 | var last = temp.lastIndexOf(' '); // 找到空格的索引 57 | temp = null; // 内存回收 58 | return str.slice(0, last) + '...'; 59 | } 60 | return str; 61 | }, 62 | 63 | /* 此处只演示基于cookie的存储方法 | flag标识: 0 -> ip用户(匿名) , 1 -> 正常用户 */ 64 | /* isLogin为同步存储的登录标识 */ 65 | storage: function(data, flag, callback) { 66 | var expireDate = new Date(); 67 | expireDate.setDate(expireDate.getDate() + 90); // 设置过期时间为3个月(90天) 68 | $cookies.put('token', data.token, { 'expires': expireDate }); // cookie 存储token 69 | $cookies.put('user', JSON.stringify(data), { 'expires': expireDate }); // cookie 存储 userInfo 70 | 71 | // 下面是为正常用户和匿名ip用户的设置,登录与否的标识是isLogin 72 | flag ? $cookies.put('isLogin', true, { 'expires': expireDate }) : $cookies.remove('isLogin'); 73 | callback && angular.isFunction(callback) && callback(); 74 | }, 75 | 76 | /* 判断是否登录 */ 77 | isLogin: function() { 78 | return $cookies.get('isLogin'); 79 | }, 80 | 81 | /* 退出功能 */ 82 | logout: function(fn) { 83 | $cookies.remove('user'); 84 | $cookies.remove('token'); 85 | $cookies.remove('isLogin'); 86 | fn && typeof fn === "function" && fn(); 87 | }, 88 | 89 | /* 获取用户信息 */ 90 | getUser: function() { 91 | return $cookies.get('user'); 92 | }, 93 | 94 | /* 用户提示功能 */ 95 | tips: function(prompt, index) { 96 | // 位置信息 0 上 , 1 中 , 2 下 97 | switch (index) { 98 | case 0: 99 | return window.cordova ? $cordovaToast.showShortTop(prompt) : alert(prompt); 100 | break; 101 | case 1: 102 | return window.cordova ? $cordovaToast.showShortCenter(prompt) : alert(prompt); 103 | break; 104 | case 2: 105 | return window.cordova ? $cordovaToast.showShortBottom(prompt) : alert(prompt); 106 | break; 107 | } 108 | }, 109 | 110 | /* 弹出模态窗口功能 */ 111 | showModal: function(path, scope, animation, cb) { 112 | $ionicModal.fromTemplateUrl(path, { 113 | scope: scope, 114 | animation: animation 115 | }).then(function(modal) { 116 | cb && angular.isFunction(cb) && cb(modal); 117 | }); 118 | }, 119 | 120 | /* 隐藏 modal */ 121 | hideModal: function(modal) { 122 | modal.hide(); 123 | }, 124 | 125 | /* 移除 modal 支持多个modal一起移除 */ 126 | destroyModal: function(scope, modal) { 127 | scope.$on('$destroy', function() { 128 | // 如果是单个,则直接移出,如果是数组,则迭代移除 129 | if (Array.isArray(modal)) { 130 | modal.forEach(function(item) { 131 | item.remove(); 132 | }) 133 | } else { 134 | modal && modal.remove(); 135 | } 136 | }); 137 | }, 138 | 139 | /* 清除历史记录功能,每次回到tab根目录调用,修复ionic偶尔无法回退bug */ 140 | clearHistory: function() { 141 | $ionicHistory.clearHistory(); 142 | }, 143 | 144 | /* pdf的方法 */ 145 | openPdf: function(url) { 146 | // 安卓平台进入pdf模块打开,使用的是嵌入了一个pdf的h5网页(后台处理之后的页面) 147 | if (!ionic.Platform.isIOS()) { 148 | return this.go('pdf', { pdf: url }); 149 | } 150 | // iOS平台通过内置safari打开 151 | var options = { 152 | location: 'yes', 153 | clearcache: 'yes', 154 | toolbar: 'yes' 155 | }; 156 | // 下面此处只有真机能够打开,浏览器打不开 157 | document.addEventListener("deviceready", function() { 158 | $cordovaInAppBrowser.open(url, '_system', options) 159 | }, false); 160 | }, 161 | 162 | /* 测试用户是否登录 */ 163 | checkAndGoLogin: function(cb1, cb2) { 164 | var flag = this.isLogin(); // 是否登录 165 | if (flag) return cb1(); 166 | this.go('login', null, cb2); 167 | }, 168 | 169 | /* 数组去重功能 */ 170 | arrayUnique: function(arr) { 171 | if (!Array.isArray(arr)) return; 172 | var res = []; 173 | var json = {}; 174 | for (var i = 0; i < arr.length; i++) { 175 | if (!json[arr[i]]) { 176 | res.push(arr[i]); 177 | json[arr[i]] = 1; 178 | } 179 | } 180 | return res; 181 | }, 182 | 183 | /* 存储搜索记录 */ 184 | getSearchTextStorage: function(searchText) { 185 | var searchList = []; 186 | var res = []; 187 | if (localStorage.searchList && searchText) { 188 | searchList = JSON.parse(localStorage.searchList); 189 | searchList.unshift(searchText); // 头部加1 190 | res = this.arrayUnique(searchList); // 数组去重 191 | } else if (!localStorage.searchList && searchText) { 192 | res.unshift(searchText); 193 | } else { 194 | return localStorage.searchList ? JSON.parse(localStorage.searchList) : []; 195 | } 196 | localStorage.searchList = JSON.stringify(res); // 本地存储 197 | return res; 198 | }, 199 | /* 键盘监听 只针对安卓,ios会自动处理 */ 200 | /* 其中window.addEventListener可使用ionic内置的 ionic.EventController.on代替 */ 201 | listenKeyBoard: function(cb_show, cb_hide) { 202 | if (ionic.Platform.isIOS()) return; 203 | window.addEventListener('native.keyboardshow', function() { 204 | cb_show && typeof cb_show === 'function' && cb_show(); 205 | }); 206 | window.addEventListener('native.keyboardhide', function() { 207 | cb_hide && typeof cb_hide === 'function' && cb_hide(); 208 | }); 209 | }, 210 | 211 | /* 隐藏键盘 */ 212 | hideKeyBoard: function() { 213 | if (!$cordovaKeyboard.isVisible()) return; 214 | $cordovaKeyboard.close(); 215 | }, 216 | 217 | /* 媒体文件相关功能 */ 218 | 219 | /* 用于判断数字是否 < 10 , < 10 则补0 */ 220 | tenFormat: function(num) { 221 | return num / 10 < 1 ? '0' + num : num; 222 | }, 223 | 224 | /* 处理时分秒 */ 225 | handleTime: function(hour, min, sec) { 226 | var hh = this.tenFormat(hour); 227 | var mm = this.tenFormat(min); 228 | var ss = this.tenFormat(sec); 229 | return hh + ':' + mm + ':' + ss; 230 | }, 231 | 232 | /* 获取音频或视频时长 */ 233 | getMediaDuration: function(scope, media, mediaData) { 234 | if (!media.duration) { 235 | return; 236 | } 237 | mediaData.current = mediaData.duration = '00:00:00'; // 先初始化时间 238 | mediaData.durationOrigin = media.duration; // 得到音频或视频时长 239 | var hh = Math.floor(media.duration / 3600); 240 | var mm = Math.floor(media.duration % 3600 / 60); 241 | var ss = Math.floor(media.duration % 60); 242 | mediaData.duration = this.handleTime(hh, mm, ss); // 得到经过格式转换之后的音频或视频时长 243 | scope.$apply(); 244 | }, 245 | 246 | /* 检查媒体时长 */ 247 | checkToGetMediaDuration: function(scope, media, mediaData) { 248 | !mediaData.durationOrigin && this.getMediaDuration(scope, media, mediaData); 249 | }, 250 | 251 | /* 处理正在进行的时间 格式为: hh:mm:ss */ 252 | handlePlayingTime: function(time) { 253 | var hh = Math.floor(time / 3600); 254 | var mm = Math.floor(time % 3600 / 60); 255 | var ss = Math.floor(time % 60); 256 | return this.handleTime(hh, mm, ss); 257 | }, 258 | // 隐藏闪屏 259 | enterSettings: function() { 260 | navigator.splashscreen && navigator.splashscreen.hide && navigator.splashscreen.hide(); // 设置闪屏 261 | window.StatusBar && window.StatusBar.show(); // 显示状态栏 262 | }, 263 | 264 | // 滚动到最顶部方法 265 | scrollToTop: function(name, flag) { 266 | $ionicScrollDelegate.$getByHandle(name).scrollTop(flag); 267 | } 268 | }; 269 | 270 | return new Util(); 271 | } 272 | ]); 273 | })(angular); 274 | -------------------------------------------------------------------------------- /src/media/audio/music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/src/media/audio/music.mp3 -------------------------------------------------------------------------------- /src/pages/account/account.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('AccountCtrl', ['$scope', function($scope) { 3 | $scope.settings = { 4 | enableFriends: true 5 | }; 6 | }]); 7 | -------------------------------------------------------------------------------- /src/pages/account/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Enable Friends 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/pages/account/account.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('tab.account', { 5 | url: '/account', 6 | views: { 7 | 'tab-account': { 8 | templateUrl: 'pages/account/account.html', 9 | controller: 'AccountCtrl' 10 | } 11 | } 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/pages/category/category.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('CategoryCtrl', [ 3 | '$scope', 4 | '$http', 5 | '$timeout', 6 | '$ionicScrollDelegate', 7 | 'appUtils', 8 | function($scope, $http, $timeout, $ionicScrollDelegate, appUtils) { 9 | /* 初始化数据模型 */ 10 | $scope.isLoading = false; 11 | var fn = $scope.fn = {}; 12 | fn.go = appUtils.go; 13 | var dataAll = $scope.dataAll = {}; 14 | 15 | // 视图事件 16 | $scope.$on('$ionicView.beforeEnter', function() { 17 | getAllCategory(); // 获取数据,本地或者从网络获取 18 | }); 19 | 20 | // 对请求过来的数据进行聚类处理 21 | function handleData(data) { 22 | angular.forEach(data, function(item) { 23 | if (item.firstletter) { 24 | dataAll.cate[item.firstletter] = dataAll.cate[item.firstletter] || []; // 初始化单元 25 | dataAll.cate[item.firstletter].push(item); 26 | } 27 | }); 28 | 29 | // 下面将是数据的格式转换 将存在的ABC标签存放到 dataAll.abc 中 30 | for (var k in dataAll.cate) { 31 | dataAll.abc.push(k); 32 | dataAll.mapContainer[k] = dataAll.cate[k].length; // 存储每个字母结点代表的分类的学科个数。 33 | } 34 | 35 | $scope.$broadcast("cate:boxCount", dataAll.abc.length); // 使用广播方式传递数据 36 | dataAll.abc.sort(); // 从A到Z排序 37 | } 38 | 39 | // 得到所有分类信息 40 | function getAllCategory() { 41 | dataAll.abc = []; 42 | dataAll.cate = {}; 43 | dataAll.mapContainer = {}; // 初始化一个盛放各个标签节点个数的对象 44 | 45 | // 如果是真实数据,那么先判断本地是否存在,如果不存在,那么网络获取,如果存在,直接使用。 46 | // 模拟请求 47 | $http.get("/data/category.json") 48 | .success(function (data) { 49 | // 判断是否有数据 50 | if (!(data && data.length)) { 51 | return; 52 | } 53 | // 处理数据 54 | handleData(data); 55 | }); 56 | } 57 | 58 | // 接收广播事件 59 | $scope.$on('cate:touchMove', function(event, data) { 60 | getScrollData(data); 61 | }); 62 | // 隐藏悬浮的字母 63 | $scope.$on('cate:touchEnd', function(event, data) { 64 | if (!data) { 65 | return; 66 | } 67 | // 0.3s之后隐藏 68 | var t = $timeout(function() { 69 | dataAll.letter = ''; 70 | $timeout.cancel(t); 71 | }, 300); 72 | }); 73 | // 接收click广播 74 | $scope.$on('cate:touchBarClick', function(event, data) { 75 | getScrollData(data); 76 | }); 77 | 78 | // 通用获取滚动事件 79 | function getScrollData(data) { 80 | var distance = data.distance; 81 | var unit = data.boxUnit; 82 | var num = Math.ceil(distance / unit) - 1; 83 | num = num < 0 ? 0 : num; // 对num进行过滤处理 84 | dataAll.letter = dataAll.abc[num]; 85 | getScrollDistanceByLetter(dataAll.letter); // 根据字母开始滚动 86 | $scope.$apply(); 87 | } 88 | 89 | // 根据字母计算滚动的距离 90 | function getScrollDistanceByLetter(letter) { 91 | // 特殊情况 A 92 | if (letter === 'A') { 93 | return $ionicScrollDelegate.$getByHandle('cateContScroll').scrollTo(0, 0, false); // 滚动特效 94 | } 95 | 96 | var initHeight = 0; // 初始高度 97 | // 循环累加,算出距离 98 | for (var k in dataAll.abc) { 99 | var item = dataAll.abc[k]; // 单项 100 | // 直到和字母相同跳出循环 101 | if (item === letter) { 102 | break; 103 | } 104 | var count = dataAll.mapContainer[item]; 105 | initHeight += (22 + 61 * count); 106 | } 107 | $ionicScrollDelegate.$getByHandle('cateContScroll').scrollTo(0, initHeight, false); // 滚动特效 108 | } 109 | 110 | } 111 | ]) 112 | .directive('categoryTouchBar', function() { 113 | return { 114 | restrict: 'EA', 115 | replace: true, 116 | link: function(scope, element) { 117 | var ele = element[0]; // 获取元素 118 | var eleTop = 0; // touchBar元素距离浏览器顶部位置初始化 119 | var eleClientRectTop = ele.getBoundingClientRect().top; // touchBar中心位置距离顶部的距离 120 | 121 | var touchEnd = 0; // 移动结束的位置 122 | var distance = 0; // 移动的距离 123 | 124 | // 初始化其他用到的数据 125 | var boxUnit = 16; // 此处是固定的单元字母高度 126 | var boxHeight = 0; // 初始化盒子高度 127 | 128 | /* 接收获取的广播数据 */ 129 | scope.$on("cate:boxCount", function(e, data) { 130 | if (!data) { 131 | return; 132 | } 133 | boxHeight = data * boxUnit; // 通过网络获取,计算得出整体高度 134 | }); 135 | 136 | // 滑动开始 137 | ionic.EventController.on('touchstart', function(e) { 138 | e.preventDefault(); 139 | eleTop = eleClientRectTop - boxHeight / 2; // 计算元素顶部距离浏览器顶部的位置 140 | }, ele); 141 | 142 | // 滑动中 143 | ionic.EventController.on('touchmove', function(e) { 144 | e.preventDefault(); 145 | touchEnd = e.touches[0].clientY; 146 | distance = touchEnd - eleTop; 147 | distance = distance > boxHeight ? boxHeight : (distance < 0 ? 0 : distance); // 超出过滤功能 148 | 149 | // boxHeight是touchBar的高度, boxUnit是每个字符的高度, distance 是最后在touchBar上的位置距离touchBar顶部的位置。 150 | var moveObj = { 151 | boxHeight: boxHeight, 152 | boxUnit: boxUnit, 153 | distance: distance 154 | }; 155 | 156 | scope.$emit('cate:touchMove', moveObj); // 发送广播 157 | }, ele); 158 | 159 | // 滑动结束隐藏 160 | ionic.EventController.on('touchend', function() { 161 | scope.$emit('cate:touchEnd', 1); // 发送广播 162 | }, ele); 163 | 164 | // 对单纯点击的支持 165 | ionic.EventController.on('click', function(e) { 166 | var moveObj = { 167 | boxHeight: boxHeight, 168 | boxUnit: boxUnit, 169 | distance: (e.pageY || e.y) - eleTop 170 | }; 171 | scope.$emit('cate:touchBarClick', moveObj); // 发送广播 172 | }, ele); 173 | } 174 | }; 175 | }); -------------------------------------------------------------------------------- /src/pages/category/category.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
{{one}}
9 | 14 |
15 |
16 | 17 |
    18 |
  • {{item}}
  • 19 |
20 |
21 | 22 |
{{dataAll.letter}}
23 |
-------------------------------------------------------------------------------- /src/pages/category/category.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('tab.category', { 5 | url: '/category', 6 | views: { 7 | 'tab-category': { 8 | templateUrl: 'pages/category/category.html', 9 | controller: 'CategoryCtrl' 10 | } 11 | } 12 | }) 13 | }); 14 | -------------------------------------------------------------------------------- /src/pages/chatDetail/chatDetail.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('ChatDetailCtrl', ['$scope', '$stateParams', 'Chats', function($scope, $stateParams, Chats) { 3 | $scope.chat = Chats.get($stateParams.chatId); 4 | }]); 5 | -------------------------------------------------------------------------------- /src/pages/chatDetail/chatDetail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

9 | {{chat.lastText}} 10 |

11 |
12 |
13 | -------------------------------------------------------------------------------- /src/pages/chatDetail/chatDetail.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('tab.chat-detail', { 5 | url: '/chats/:chatId', 6 | views: { 7 | 'tab-chats': { 8 | templateUrl: 'pages/chatDetail/chatDetail.html', 9 | controller: 'ChatDetailCtrl' 10 | } 11 | } 12 | }) 13 | }); 14 | -------------------------------------------------------------------------------- /src/pages/dash/dash.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('DashCtrl', ['$scope', function($scope) {}]); 3 | -------------------------------------------------------------------------------- /src/pages/dash/dash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
Simples
4 |
5 | 6 | 7 | 8 |

simples-pdf

9 | 10 |
11 | 12 |

simples-video

13 | 14 |
15 | 16 |

simples-mp3

17 | 18 |
19 | 20 |

simples-carousel

21 | 22 |
23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /src/pages/dash/dash.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('tab.dash', { 5 | url: '/dash', 6 | views: { 7 | 'tab-dash': { 8 | templateUrl: 'pages/dash/dash.html', 9 | controller: 'DashCtrl' 10 | } 11 | } 12 | }) 13 | }); 14 | -------------------------------------------------------------------------------- /src/pages/samples/carousel/carousel.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('MarouselCtrl', [ 3 | '$scope', 4 | '$http', 5 | '$timeout', 6 | 'appUtils', 7 | 'global', 8 | function ($scope, $http, $timeout, appUtils, global) { 9 | /* 初始化数据模型 */ 10 | $scope.back = appUtils.back; 11 | $scope.magList = []; // 杂志列表 12 | $scope.volList = []; // 期列表数据 13 | $scope.curMag = '最新'; // 默认杂志 : 最新 14 | $scope.isLoading = true; // loading 默认 true 15 | var fn = $scope.fn = {}; 16 | 17 | /* 进入视图,收起 */ 18 | $scope.$on('$ionicView.beforeEnter', function () { 19 | $scope.spread = false; // 默认不展开 20 | }); 21 | 22 | // 页面初始化 23 | pageInit(); 24 | 25 | /* 页面初始化 */ 26 | function pageInit() { 27 | loadingHide(); // loading 效果 28 | getMagList(); // 获取杂志列表 29 | getLatest(); // 获取最新杂志 30 | } 31 | 32 | /* 封装通用获取数据的方法 */ 33 | function getData(url, callback) { 34 | $http.get(url) 35 | .success(function (data) { 36 | callback && callback(data); 37 | }) 38 | .error(function () { 39 | callback && callback(null); 40 | }); 41 | } 42 | 43 | /* 图片质量较大 添加延迟隐藏方法 */ 44 | function loadingHide() { 45 | var t = $timeout(function () { 46 | $scope.isLoading = false; 47 | $timeout.cancel(t); // 去除延定时器 48 | }, 300); 49 | } 50 | 51 | /* 获取杂志列表 */ 52 | function getMagList() { 53 | var json = { 54 | "magName": "最新" 55 | }; 56 | $scope.magList.push(json); 57 | getData(global.dataUrl + '/mag-list.json',function (data) { 58 | if(!data) { 59 | return; 60 | } 61 | $scope.magList = $scope.magList.concat(data); 62 | }); 63 | } 64 | 65 | /* 获取最新期 */ 66 | function getLatest(callback) { 67 | getData(global.dataUrl + '/latest.json',function (data) { 68 | if(!data) { 69 | return; 70 | } 71 | $scope.volList = data; 72 | callback && callback(); 73 | }); 74 | } 75 | 76 | /* 根据杂志code获取该杂志的期 */ 77 | function getVolByMagCode(magCode, callback) { 78 | var cb = function() { 79 | callback && callback(); 80 | } 81 | switch (magCode) { 82 | case "ECON": 83 | getData(global.dataUrl + '/eco-list.json',function (data) { 84 | if(!data) { 85 | return; 86 | } 87 | $scope.volList = data; 88 | cb(); 89 | }); 90 | break; 91 | case "BIOL": 92 | getData(global.dataUrl + '/bio-list.json',function (data) { 93 | if(!data) { 94 | return; 95 | } 96 | $scope.volList = data; 97 | cb(); 98 | }); 99 | break; 100 | case "COMP": 101 | getData(global.dataUrl + '/com-list.json',function (data) { 102 | if(!data) { 103 | return; 104 | } 105 | $scope.volList = data; 106 | cb(); 107 | }); 108 | break; 109 | default: 110 | // 分配给最新期 111 | getData(global.dataUrl + '/latest.json',function (data) { 112 | if(!data) { 113 | return; 114 | } 115 | $scope.volList = data; 116 | cb(); 117 | }); 118 | } 119 | } 120 | 121 | /* 隐藏灰层 */ 122 | fn.hideGray = function() { 123 | $scope.spread = false; 124 | } 125 | 126 | /* 杂志的点击 */ 127 | fn.switchVols = function (index, item) { 128 | $scope.spread = false; // 默认收起 129 | $scope.isLoading = $scope.curMag !== item.magName; // 表示切换了 130 | // 没有loading ,不去请求数据 131 | if (!$scope.isLoading) return; 132 | // 点击第一个获取最新数据 133 | if (!index) { 134 | $scope.curMag = '最新'; 135 | return getLatest(loadingHide); 136 | } 137 | getVolByMagCode(item.magCode, loadingHide); 138 | $scope.curMag = item.magName; 139 | } 140 | } 141 | ]); 142 | -------------------------------------------------------------------------------- /src/pages/samples/carousel/carousel.directive.js: -------------------------------------------------------------------------------- 1 | (function (angular) { 2 | "use strict"; 3 | // 定义一些通用的指令 4 | angular.module('ionic-samples') 5 | .directive('carouselSlider', function (appUtils, $compile, $timeout) { 6 | return { 7 | restrict: 'A', 8 | scope: { 9 | volList: '=', 10 | charShow: '=' 11 | }, 12 | template: '
', 13 | link: function (scope) { 14 | // 用于挂载在外部的变量, 用于处理屏幕变化的变量 15 | scope.outWatcher = {}; 16 | 17 | // 所有设置函数 18 | function setUp() { 19 | // 针对宽高比的判断 20 | // 进行轮播图的 dom 生成操作 21 | var $ = angular.element; // jqLite 对象 22 | var slideBox = scope.outWatcher.slideBox = document.querySelector('.slider-wrap'); // 获取轮播盒子对象 23 | var sliderInner = scope.outWatcher.sliderInner = document.createElement('ul'); 24 | sliderInner.className = 'slider-wrap-inner'; 25 | slideBox.appendChild(sliderInner); 26 | 27 | // 杂志点击的回调 可用于其他逻辑处理 28 | scope.magClick = function (title) { 29 | console.log(title); 30 | }; 31 | 32 | // 缩放的动画 33 | function scale(obj, rate) { 34 | if (!obj) return; 35 | obj.style.transform = "scale(" + rate + ")"; 36 | obj.style.webkitTransform = "scale(" + rate + ")"; 37 | } 38 | 39 | // 获取数据 40 | function getData(list, callback) { 41 | // 通过获得的数据,生成节点操作 42 | for (var i = 0; i < list.length; i++) { 43 | var li = document.createElement('li'); 44 | var img = document.createElement('img'); 45 | var imgWrap = document.createElement('div'); 46 | imgWrap.className = 'img-wrap'; 47 | img.src = 'images/transparent.gif'; 48 | // 首先先加载前三张图片的地址,其他的作懒加载处理 49 | if (i < 3) { 50 | img.setAttribute('style', 'background-image:url(' + list[i].coverimg + ')'); 51 | } 52 | imgWrap.appendChild(img); 53 | li.appendChild(imgWrap); 54 | li.setAttribute('on-tap', 'magClick("' + list[i].title + '")'); // 绑定事件 55 | $(sliderInner).append($(li)); 56 | } 57 | var htmlObj = $compile($(sliderInner).html())(scope); // 对html 进行重新编译 58 | $(sliderInner).html(''); // 清空 59 | $(sliderInner).append(htmlObj); // 追加 60 | var lis = sliderInner.querySelectorAll('li'); // 得到当前的所有li对象 61 | var imgs = scope.outWatcher.imgs = []; // 用于存放图像包裹节点 62 | // 图像包裹节点数组, 初始化样式 63 | for (var k = 0; k < lis.length; k++) { 64 | if (!k) { 65 | imgs.push(lis[0].querySelector('.img-wrap')); // 第一个只 push 进去 ,不 设置样式 66 | continue; 67 | } 68 | var item = lis[k].querySelector('.img-wrap'); 69 | scale(item, 252 / 291); // 样式初始化缩放 70 | imgs.push(item); // 并push 71 | } 72 | callback && angular.isFunction(callback) && callback(imgs, list); // 将数据通过callback带走 73 | } 74 | 75 | // 针对杂志切换,数据同时切换 76 | scope.$watch('volList', function (now) { 77 | if (now && now.length) { 78 | sliderInner.innerHTML = ''; // 先清空内容 79 | // 使用$timeout来解决宽度问题,重新渲染dom. 80 | $timeout(function(){ 81 | getData(now, function (imgs, now) { 82 | var m = new MobileMove(); // 重新new 83 | m.setSwipe(slideBox, sliderInner, imgs, now); 84 | }); 85 | }); 86 | } 87 | }); 88 | } 89 | 90 | // 监听屏幕变化事件, 随时构造对象 91 | window.onresize = function() { 92 | var m = new MobileMove(); // 重新new 93 | m.setSwipe(scope.outWatcher.slideBox, scope.outWatcher.sliderInner, scope.outWatcher.imgs, scope.volList); 94 | } 95 | 96 | // 页面加载完成后执行 97 | var contentLoaded = scope.$watch('$viewContentLoaded', function() { 98 | setUp(); // 全面设置 99 | contentLoaded(); // 取消 watch 100 | }); 101 | } 102 | }; 103 | }) 104 | })(angular); 105 | -------------------------------------------------------------------------------- /src/pages/samples/carousel/carousel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |

缩放Banner

7 |
8 | 10 | 11 |
12 |
13 |
14 | 15 | 16 |
17 | 18 |
19 |
20 | 杂志·{{curMag}} 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 |
29 | 31 |
    32 |
  • 33 | {{item.magName}} 34 |
  • 35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 | -------------------------------------------------------------------------------- /src/pages/samples/carousel/carousel.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('carousel', { 5 | url: '/samples/carousel', 6 | templateUrl: 'pages/samples/carousel/carousel.html', 7 | controller: 'MarouselCtrl' 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /src/pages/samples/mp3/mp3.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('Mp3Ctrl', [ 3 | '$scope', 4 | '$sce', 5 | 'appUtils', 6 | 'global', 7 | function($scope, $sce, appUtils, global) { 8 | $scope.back = appUtils.back; 9 | var renderData = $scope.renderData = {}; 10 | var sourceUrl = global.mediaUrl + '/audio/music.mp3'; 11 | console.log("sourceUrl: ", sourceUrl); 12 | renderData.source = $sce.trustAsResourceUrl(sourceUrl); 13 | 14 | // 接收广播事件 15 | $scope.$on('audio:playState', function(event, data) { 16 | renderData.playAnimation = data; 17 | }); 18 | } 19 | ]); 20 | -------------------------------------------------------------------------------- /src/pages/samples/mp3/mp3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |

音频播放

7 |
8 | 9 | 10 |
11 |
12 | music 13 |
14 |
15 |
16 |
17 | 18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /src/pages/samples/mp3/mp3.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('mp3', { 5 | url: '/samples/mp3', 6 | templateUrl: 'pages/samples/mp3/mp3.html', 7 | controller: 'Mp3Ctrl' 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /src/pages/samples/pdf/pdf.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('PdfCtrl', [ 3 | '$scope', 4 | '$sce', 5 | 'appUtils', 6 | 'global', 7 | function($scope, $sce, appUtils, global) { 8 | var pdfUrl = 'https://mozilla.github.io/pdf.js/web/viewer.html'; 9 | $scope.pdfSrc = $sce.trustAsResourceUrl(pdfUrl); 10 | $scope.back = appUtils.back; 11 | } 12 | ]); 13 | -------------------------------------------------------------------------------- /src/pages/samples/pdf/pdf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |

PDF预览

7 |
8 | 9 | 10 |
11 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /src/pages/samples/pdf/pdf.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('pdf', { 5 | url: '/samples/pdf', 6 | templateUrl: 'pages/samples/pdf/pdf.html', 7 | controller: 'PdfCtrl' 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /src/pages/samples/video/video.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('VideoCtrl', [ 3 | '$scope', 4 | '$sce', 5 | 'appUtils', 6 | function($scope, $sce, appUtils) { 7 | $scope.back = appUtils.back; 8 | var renderData = $scope.renderData = {}; 9 | renderData.videoSrc = $sce.trustAsResourceUrl('http://static.videogular.com/assets/videos/videogular.mp4'); 10 | renderData.hideBar = false; // 控制是否隐藏 bar 11 | 12 | /* 视图事件 */ 13 | $scope.$on('$ionicView.afterEnter', function() { 14 | // 锁定屏幕,让其全屏横屏显示 15 | if (!window.cordova) { 16 | return; 17 | } 18 | window.screen.orientation.lock('landscape'); 19 | }); 20 | $scope.$on('$ionicView.afterLeave', function() { 21 | // 还原成竖屏 22 | if (!window.cordova) { 23 | return; 24 | } 25 | window.screen.orientation.lock('portrait'); 26 | }); 27 | 28 | // 接收广播 29 | $scope.$on('videoBarHide', function(event, data) { 30 | if (!data) { 31 | return; 32 | } 33 | renderData.hideBar = true; 34 | $scope.$apply(); 35 | }); 36 | $scope.$on('videoBarShow', function(event, data) { 37 | if (!data) { 38 | return; 39 | } 40 | renderData.hideBar = false; 41 | $scope.$apply(); 42 | }); 43 | } 44 | ]); 45 | -------------------------------------------------------------------------------- /src/pages/samples/video/video.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |

video预览

7 |
8 | 9 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /src/pages/samples/video/video.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('video', { 5 | url: '/samples/video', 6 | templateUrl: 'pages/samples/video/video.html', 7 | controller: 'VideoCtrl' 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /src/pages/tab/tab.controller.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .controller('TabCtrl', function($scope) {}); 3 | -------------------------------------------------------------------------------- /src/pages/tab/tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/pages/tab/tab.route.js: -------------------------------------------------------------------------------- 1 | angular.module('ionic-samples') 2 | .config(function($stateProvider) { 3 | $stateProvider 4 | .state('tab', { 5 | url: '/tab', 6 | abstract: true, 7 | templateUrl: 'pages/tab/tab.html', 8 | controller: 'TabCtrl' 9 | }) 10 | }); 11 | -------------------------------------------------------------------------------- /www/app/app.templates.1517145267382.min.js: -------------------------------------------------------------------------------- 1 | angular.module("templates",[]).run(["$templateCache",function(a){a.put("pages/account/account.html",'Enable Friends'),a.put("pages/category/category.html",'
  • {{item}}
\x3c!-- 展示字母 --\x3e
{{dataAll.letter}}
'),a.put("pages/chatDetail/chatDetail.html",'

{{chat.lastText}}

'),a.put("pages/dash/dash.html",'
Simples

simples-pdf

simples-video

simples-mp3

simples-carousel

'),a.put("pages/tab/tab.html",'\x3c!-- Dashboard Tab --\x3e\x3c!-- Chats Tab --\x3e\x3c!-- Account Tab --\x3e'),a.put("pages/directives/html/mp3.html",'
\x3c!-- 音频控制区 --\x3e
\x3c!-- 播放,暂停 --\x3e
{{audioData.current ? audioData.current : \'00:00:00\'}} {{audioData.duration ? audioData.duration : \'00:00:00\'}}
'),a.put("pages/directives/html/video.html",'
\x3c!-- 视频源 --\x3e\x3c!-- 视频播放控制区 --\x3e
\x3c!-- 播放,暂停 --\x3e
{{videoData.current ? videoData.current : \'00:00:00\'}}/{{videoData.duration ? videoData.duration : \'00:00:00\'}}
\x3c!-- 视频缓冲loading --\x3e
'),a.put("pages/samples/carousel/carousel.html",'

缩放Banner

\x3c!-- 轮播部分 --\x3e
\x3c!-- loading部分 --\x3e
\x3c!-- 杂志层 --\x3e
杂志·{{curMag}}\x3c!-- 两个三角 --\x3e
\x3c!-- 下拉菜单 --\x3e
  • {{item.magName}}
\x3c!-- 灰层 --\x3e
'),a.put("pages/samples/mp3/mp3.html",'

音频播放

\x3c!-- 动画区域 --\x3e
music
\x3c!-- audio元素 --\x3e
'),a.put("pages/samples/pdf/pdf.html",'

PDF预览

\x3c!-- 用于显示iframe加载中的进度条 --\x3e
'),a.put("pages/samples/video/video.html",'

video预览

')}]); -------------------------------------------------------------------------------- /www/assets/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/ionicons.eot -------------------------------------------------------------------------------- /www/assets/fonts/ionicons.scss: -------------------------------------------------------------------------------- 1 | 2 | // Ionicons Icon Font CSS 3 | // -------------------------- 4 | // Ionicons CSS for Ionic's element 5 | // ionicons-icons.scss has the icons and their unicode characters 6 | 7 | $ionicons-font-path: $font-path !default; 8 | 9 | @import "ionicons-icons"; 10 | @import "ionicons-variables"; 11 | 12 | 13 | @font-face { 14 | font-family: "Ionicons"; 15 | src: url("#{$ionicons-font-path}/ionicons.woff2?v=#{$ionicons-version}") format("woff2"), 16 | url("#{$ionicons-font-path}/ionicons.woff?v=#{$ionicons-version}") format("woff"), 17 | url("#{$ionicons-font-path}/ionicons.ttf?v=#{$ionicons-version}") format("truetype"); 18 | font-weight: normal; 19 | font-style: normal; 20 | } 21 | 22 | ion-icon { 23 | display: inline-block; 24 | 25 | font-family: "Ionicons"; 26 | -moz-osx-font-smoothing: grayscale; 27 | -webkit-font-smoothing: antialiased; 28 | font-style: normal; 29 | font-variant: normal; 30 | font-weight: normal; 31 | line-height: 1; 32 | text-rendering: auto; 33 | text-transform: none; 34 | speak: none; 35 | 36 | @include rtl() { 37 | &[aria-label^="arrow"]::before, 38 | &[flip-rtl]::before { 39 | transform: scaleX(-1); 40 | } 41 | 42 | &[unflip-rtl]::before { 43 | transform: scaleX(1); 44 | } 45 | } 46 | 47 | &::before { 48 | display: inline-block; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /www/assets/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/ionicons.ttf -------------------------------------------------------------------------------- /www/assets/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/ionicons.woff -------------------------------------------------------------------------------- /www/assets/fonts/ionicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/ionicons.woff2 -------------------------------------------------------------------------------- /www/assets/fonts/noto-sans-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/noto-sans-bold.ttf -------------------------------------------------------------------------------- /www/assets/fonts/noto-sans-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/noto-sans-bold.woff -------------------------------------------------------------------------------- /www/assets/fonts/noto-sans-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/noto-sans-regular.ttf -------------------------------------------------------------------------------- /www/assets/fonts/noto-sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/noto-sans-regular.woff -------------------------------------------------------------------------------- /www/assets/fonts/noto-sans.scss: -------------------------------------------------------------------------------- 1 | // Noto Sans Font 2 | // Google 3 | // Apache License, version 2.0 4 | // http://www.apache.org/licenses/LICENSE-2.0.html 5 | 6 | $noto-sans-font-path: $font-path !default; 7 | 8 | @font-face { 9 | font-family: "Noto Sans"; 10 | font-style: normal; 11 | font-weight: 300; 12 | src: local("Noto Sans"), local("Noto-Sans-Regular"), url("#{$noto-sans-font-path}/noto-sans-regular.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-regular.ttf") format("truetype"); 13 | } 14 | 15 | @font-face { 16 | font-family: "Noto Sans"; 17 | font-style: normal; 18 | font-weight: 400; 19 | src: local("Noto Sans"), local("Noto-Sans-Regular"), url("#{$noto-sans-font-path}/noto-sans-regular.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-regular.ttf") format("truetype"); 20 | } 21 | 22 | @font-face { 23 | font-family: "Noto Sans"; 24 | font-style: normal; 25 | font-weight: 500; 26 | src: local("Noto Sans Bold"), local("Noto-Sans-Bold"), url("#{$noto-sans-font-path}/noto-sans-bold.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-bold.ttf") format("truetype"); 27 | } 28 | 29 | @font-face { 30 | font-family: "Noto Sans"; 31 | font-style: normal; 32 | font-weight: 700; 33 | src: local("Noto Sans Bold"), local("Noto-Sans-Bold"), url("#{$noto-sans-font-path}/noto-sans-bold.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-bold.ttf") format("truetype"); 34 | } 35 | -------------------------------------------------------------------------------- /www/assets/fonts/roboto-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-bold.ttf -------------------------------------------------------------------------------- /www/assets/fonts/roboto-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-bold.woff -------------------------------------------------------------------------------- /www/assets/fonts/roboto-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-bold.woff2 -------------------------------------------------------------------------------- /www/assets/fonts/roboto-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-light.ttf -------------------------------------------------------------------------------- /www/assets/fonts/roboto-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-light.woff -------------------------------------------------------------------------------- /www/assets/fonts/roboto-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-light.woff2 -------------------------------------------------------------------------------- /www/assets/fonts/roboto-medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-medium.ttf -------------------------------------------------------------------------------- /www/assets/fonts/roboto-medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-medium.woff -------------------------------------------------------------------------------- /www/assets/fonts/roboto-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-medium.woff2 -------------------------------------------------------------------------------- /www/assets/fonts/roboto-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-regular.ttf -------------------------------------------------------------------------------- /www/assets/fonts/roboto-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-regular.woff -------------------------------------------------------------------------------- /www/assets/fonts/roboto-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/fonts/roboto-regular.woff2 -------------------------------------------------------------------------------- /www/assets/fonts/roboto.scss: -------------------------------------------------------------------------------- 1 | // Roboto Font 2 | // Google 3 | // Apache License, version 2.0 4 | // http://www.apache.org/licenses/LICENSE-2.0.html 5 | 6 | $roboto-font-path: $font-path !default; 7 | 8 | @font-face { 9 | font-family: "Roboto"; 10 | font-style: normal; 11 | font-weight: 300; 12 | src: local("Roboto Light"), local("Roboto-Light"), url("#{$roboto-font-path}/roboto-light.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-light.woff") format("woff"), url("#{$roboto-font-path}/roboto-light.ttf") format("truetype"); 13 | } 14 | 15 | @font-face { 16 | font-family: "Roboto"; 17 | font-style: normal; 18 | font-weight: 400; 19 | src: local("Roboto"), local("Roboto-Regular"), url("#{$roboto-font-path}/roboto-regular.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-regular.woff") format("woff"), url("#{$roboto-font-path}/roboto-regular.ttf") format("truetype"); 20 | } 21 | 22 | @font-face { 23 | font-family: "Roboto"; 24 | font-style: normal; 25 | font-weight: 500; 26 | src: local("Roboto Medium"), local("Roboto-Medium"), url("#{$roboto-font-path}/roboto-medium.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-medium.woff") format("woff"), url("#{$roboto-font-path}/roboto-medium.ttf") format("truetype"); 27 | } 28 | 29 | @font-face { 30 | font-family: "Roboto"; 31 | font-style: normal; 32 | font-weight: 700; 33 | src: local("Roboto Bold"), local("Roboto-Bold"), url("#{$roboto-font-path}/roboto-bold.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-bold.woff") format("woff"), url("#{$roboto-font-path}/roboto-bold.ttf") format("truetype"); 34 | } 35 | -------------------------------------------------------------------------------- /www/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/icon/favicon.ico -------------------------------------------------------------------------------- /www/assets/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/assets/imgs/logo.png -------------------------------------------------------------------------------- /www/audio/music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/audio/music.mp3 -------------------------------------------------------------------------------- /www/build/main.css.map: -------------------------------------------------------------------------------- 1 | null -------------------------------------------------------------------------------- /www/build/main.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../node_modules/@angular/core/esm5 lazy","../../src lazy","../../src/pages/tabs/tabs.ts","../../src/pages/about/about.ts","../../src/pages/contact/contact.ts","../../src/pages/home/home.ts","../../src/app/main.ts","../../src/app/app.module.ts","../../src/app/app.component.ts"],"names":[],"mappings":";;;;;AAAA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA,4CAA4C,WAAW;AACvD;AACA;AACA,kC;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA,4CAA4C,WAAW;AACvD;AACA;AACA,kC;;;;;;;;;;;;;;;;;;;;;;ACV0C;AAEC;AACM;AACT;AAKxC;IAME;QAJA,aAAQ,GAAG,4DAAQ,CAAC;QACpB,aAAQ,GAAG,+DAAS,CAAC;QACrB,aAAQ,GAAG,qEAAW,CAAC;IAIvB,CAAC;IARU,QAAQ;QAHpB,wEAAS,CAAC;WACe;SACzB,CAAC;;OACW,QAAQ,CASpB;IAAD,CAAC;AAAA;SATY,QAAQ,e;;;;;;;;;;;;;;;;;;;;ACTqB;AACI;AAM9C;IAEE,mBAAmB,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAEzC,CAAC;IAJU,SAAS;QAJrB,wEAAS,CAAC;YACT,QAAQ,EAAE,YAAY;WACG;SAC1B,CAAC;kBAGyC;OAF9B,SAAS,CAMrB;IAAD,CAAC;AAAA;SANY,SAAS,e;;;;;;;;;;;;;;;;;;;;ACPoB;AACI;AAM9C;IAEE,qBAAmB,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAEzC,CAAC;IAJU,WAAW;QAJvB,wEAAS,CAAC;YACT,QAAQ,EAAE,cAAc;WACG;SAC5B,CAAC;oBAGyC;OAF9B,WAAW,CAMvB;IAAD,CAAC;AAAA;SANY,WAAW,e;;;;;;;;;;;;;;;;;;;;ACPkB;AACI;AAM9C;IAEE,kBAAmB,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAEzC,CAAC;IAJU,QAAQ;QAJpB,wEAAS,CAAC;YACT,QAAQ,EAAE,WAAW;WACG;SACzB,CAAC;iBAGyC;OAF9B,QAAQ,CAMpB;IAAD,CAAC;AAAA;SANY,QAAQ,e;;;;;;;;;;;ACPsD;AAElC;AAEzC,yGAAsB,EAAE,CAAC,eAAe,CAAC,8DAAS,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;ACJG;AACG;AACe;AACjC;AAES;AACM;AACT;AACA;AAEO;AACM;AAiC3D;IAAA;IAAwB,CAAC;IAAZ,SAAS;QA/BrB,uEAAQ,CAAC;YACR,YAAY,EAAE;gBACZ,6DAAK;gBACL,qEAAS;gBACT,2EAAW;gBACX,kEAAQ;gBACR,kEAAQ;aACT;YACD,OAAO,EAAE;gBACP,gFAAa;gBACb,kEAAW,CAAC,OAAO,CAAC,6DAAK,EAAE,EAAE,EACjC;oBACE,KAAK,EAAE,EAEN;iBACF,CAAC;aACC;YACD,SAAS,EAAE,CAAC,+DAAQ,CAAC;YACrB,eAAe,EAAE;gBACf,6DAAK;gBACL,qEAAS;gBACT,2EAAW;gBACX,kEAAQ;gBACR,kEAAQ;aACT;YACD,SAAS,EAAE;gBACT,2EAAS;gBACT,iFAAY;gBACZ,EAAC,OAAO,EAAE,mEAAY,EAAE,QAAQ,EAAE,wEAAiB,EAAC;aACrD;SACF,CAAC;OACW,SAAS,CAAG;IAAD,gBAAC;CAAA;AAAH;;;;;;;;;;;;;;;;;;;;;;;;AC5CoB;AACD;AACY;AACM;AAEb;AAK9C;IAGE,eAAY,QAAkB,EAAE,SAAoB,EAAE,YAA0B;QAFhF,aAAQ,GAAO,kEAAQ,CAAC;QAGtB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC;YACpB,gEAAgE;YAChE,iEAAiE;YACjE,SAAS,CAAC,YAAY,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAVU,KAAK;QAHjB,wEAAS,CAAC;WACc;SACxB,CAAC;cAIgF;OAHrE,KAAK,CAWjB;IAAD,CAAC;AAAA;SAXY,KAAK,2B","file":"main.js","sourcesContent":["function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncatched exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = 109;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@angular/core/esm5 lazy\n// module id = 109\n// module chunks = 0","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncatched exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = 150;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src lazy\n// module id = 150\n// module chunks = 0","import { Component } from '@angular/core';\n\nimport { AboutPage } from '../about/about';\nimport { ContactPage } from '../contact/contact';\nimport { HomePage } from '../home/home';\n\n@Component({\n templateUrl: 'tabs.html'\n})\nexport class TabsPage {\n\n tab1Root = HomePage;\n tab2Root = AboutPage;\n tab3Root = ContactPage;\n\n constructor() {\n\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/pages/tabs/tabs.ts","import { Component } from '@angular/core';\nimport { NavController } from 'ionic-angular';\n\n@Component({\n selector: 'page-about',\n templateUrl: 'about.html'\n})\nexport class AboutPage {\n\n constructor(public navCtrl: NavController) {\n\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/pages/about/about.ts","import { Component } from '@angular/core';\nimport { NavController } from 'ionic-angular';\n\n@Component({\n selector: 'page-contact',\n templateUrl: 'contact.html'\n})\nexport class ContactPage {\n\n constructor(public navCtrl: NavController) {\n\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/pages/contact/contact.ts","import { Component } from '@angular/core';\nimport { NavController } from 'ionic-angular';\n\n@Component({\n selector: 'page-home',\n templateUrl: 'home.html'\n})\nexport class HomePage {\n\n constructor(public navCtrl: NavController) {\n\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/pages/home/home.ts","import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app.module';\n\nplatformBrowserDynamic().bootstrapModule(AppModule);\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/main.ts","import { NgModule, ErrorHandler } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\nimport { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';\nimport { MyApp } from './app.component';\n\nimport { AboutPage } from '../pages/about/about';\nimport { ContactPage } from '../pages/contact/contact';\nimport { HomePage } from '../pages/home/home';\nimport { TabsPage } from '../pages/tabs/tabs';\n\nimport { StatusBar } from '@ionic-native/status-bar';\nimport { SplashScreen } from '@ionic-native/splash-screen';\n\n@NgModule({\n declarations: [\n MyApp,\n AboutPage,\n ContactPage,\n HomePage,\n TabsPage\n ],\n imports: [\n BrowserModule,\n IonicModule.forRoot(MyApp)\n ],\n bootstrap: [IonicApp],\n entryComponents: [\n MyApp,\n AboutPage,\n ContactPage,\n HomePage,\n TabsPage\n ],\n providers: [\n StatusBar,\n SplashScreen,\n {provide: ErrorHandler, useClass: IonicErrorHandler}\n ]\n})\nexport class AppModule {}\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/app.module.ts","import { Component } from '@angular/core';\nimport { Platform } from 'ionic-angular';\nimport { StatusBar } from '@ionic-native/status-bar';\nimport { SplashScreen } from '@ionic-native/splash-screen';\n\nimport { TabsPage } from '../pages/tabs/tabs';\n\n@Component({\n templateUrl: 'app.html'\n})\nexport class MyApp {\n rootPage:any = TabsPage;\n\n constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {\n platform.ready().then(() => {\n // Okay, so the platform is ready and our plugins are available.\n // Here you can do any higher level native things you might need.\n statusBar.styleDefault();\n splashScreen.hide();\n });\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/app.component.ts"],"sourceRoot":""} -------------------------------------------------------------------------------- /www/build/sw-toolbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.toolbox=e()}}(function(){return function e(t,n,r){function o(c,s){if(!n[c]){if(!t[c]){var a="function"==typeof require&&require;if(!s&&a)return a(c,!0);if(i)return i(c,!0);var u=new Error("Cannot find module '"+c+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[c]={exports:{}};t[c][0].call(f.exports,function(e){var n=t[c][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;ct.value[l]){var r=t.value[p];c.push(r),a.delete(r),t.continue()}},s.oncomplete=function(){r(c)},s.onabort=o}):Promise.resolve([])}function s(e,t){return t?new Promise(function(n,r){var o=[],i=e.transaction(h,"readwrite"),c=i.objectStore(h),s=c.index(l),a=s.count();s.count().onsuccess=function(){var e=a.result;e>t&&(s.openCursor().onsuccess=function(n){var r=n.target.result;if(r){var i=r.value[p];o.push(i),c.delete(i),e-o.length>t&&r.continue()}})},i.oncomplete=function(){n(o)},i.onabort=r}):Promise.resolve([])}function a(e,t,n,r){return c(e,n,r).then(function(n){return s(e,t).then(function(e){return n.concat(e)})})}var u="sw-toolbox-",f=1,h="store",p="url",l="timestamp",d={};t.exports={getDb:o,setTimestampForUrl:i,expireEntries:a}},{}],3:[function(e,t,n){"use strict";function r(e){var t=a.match(e.request);t?e.respondWith(t(e.request)):a.default&&"GET"===e.request.method&&0===e.request.url.indexOf("http")&&e.respondWith(a.default(e.request))}function o(e){s.debug("activate event fired");var t=u.cache.name+"$$$inactive$$$";e.waitUntil(s.renameCache(t,u.cache.name))}function i(e){return e.reduce(function(e,t){return e.concat(t)},[])}function c(e){var t=u.cache.name+"$$$inactive$$$";s.debug("install event fired"),s.debug("creating cache ["+t+"]"),e.waitUntil(s.openCache({cache:{name:t}}).then(function(e){return Promise.all(u.preCacheItems).then(i).then(s.validatePrecacheInput).then(function(t){return s.debug("preCache list: "+(t.join(", ")||"(none)")),e.addAll(t)})}))}e("serviceworker-cache-polyfill");var s=e("./helpers"),a=e("./router"),u=e("./options");t.exports={fetchListener:r,activateListener:o,installListener:c}},{"./helpers":1,"./options":4,"./router":6,"serviceworker-cache-polyfill":16}],4:[function(e,t,n){"use strict";var r;r=self.registration?self.registration.scope:self.scope||new URL("./",self.location).href,t.exports={cache:{name:"$$$toolbox-cache$$$"+r+"$$$",maxAgeSeconds:null,maxEntries:null},debug:!1,networkTimeoutSeconds:null,preCacheItems:[],successResponses:/^0|([123]\d\d)|(40[14567])|410$/}},{}],5:[function(e,t,n){"use strict";var r=new URL("./",self.location),o=r.pathname,i=e("path-to-regexp"),c=function(e,t,n,r){t instanceof RegExp?this.fullUrlRegExp=t:(0!==t.indexOf("/")&&(t=o+t),this.keys=[],this.regexp=i(t,this.keys)),this.method=e,this.options=r,this.handler=n};c.prototype.makeHandler=function(e){var t;if(this.regexp){var n=this.regexp.exec(e);t={},this.keys.forEach(function(e,r){t[e.name]=n[r+1]})}return function(e){return this.handler(e,t,this.options)}.bind(this)},t.exports=c},{"path-to-regexp":15}],6:[function(e,t,n){"use strict";function r(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var o=e("./route"),i=e("./helpers"),c=function(e,t){for(var n=e.entries(),r=n.next(),o=[];!r.done;){var i=new RegExp(r.value[0]);i.test(t)&&o.push(r.value[1]),r=n.next()}return o},s=function(){this.routes=new Map,this.routes.set(RegExp,new Map),this.default=null};["get","post","put","delete","head","any"].forEach(function(e){s.prototype[e]=function(t,n,r){return this.add(e,t,n,r)}}),s.prototype.add=function(e,t,n,c){c=c||{};var s;t instanceof RegExp?s=RegExp:(s=c.origin||self.location.origin,s=s instanceof RegExp?s.source:r(s)),e=e.toLowerCase();var a=new o(e,t,n,c);this.routes.has(s)||this.routes.set(s,new Map);var u=this.routes.get(s);u.has(e)||u.set(e,new Map);var f=u.get(e),h=a.regexp||a.fullUrlRegExp;f.has(h.source)&&i.debug('"'+t+'" resolves to same regex as existing route.'),f.set(h.source,a)},s.prototype.matchMethod=function(e,t){var n=new URL(t),r=n.origin,o=n.pathname;return this._match(e,c(this.routes,r),o)||this._match(e,[this.routes.get(RegExp)],t)},s.prototype._match=function(e,t,n){if(0===t.length)return null;for(var r=0;r0)return s[0].makeHandler(n)}}return null},s.prototype.match=function(e){return this.matchMethod(e.method,e.url)||this.matchMethod("any",e.url)},t.exports=new s},{"./helpers":1,"./route":5}],7:[function(e,t,n){"use strict";function r(e,t,n){return n=n||{},i.debug("Strategy: cache first ["+e.url+"]",n),i.openCache(n).then(function(t){return t.match(e).then(function(t){var r=n.cache||o.cache,c=Date.now();return i.isResponseFresh(t,r.maxAgeSeconds,c)?t:i.fetchAndCache(e,n)})})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],8:[function(e,t,n){"use strict";function r(e,t,n){return n=n||{},i.debug("Strategy: cache only ["+e.url+"]",n),i.openCache(n).then(function(t){return t.match(e).then(function(e){var t=n.cache||o.cache,r=Date.now();if(i.isResponseFresh(e,t.maxAgeSeconds,r))return e})})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],9:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: fastest ["+e.url+"]",n),new Promise(function(r,c){var s=!1,a=[],u=function(e){a.push(e.toString()),s?c(new Error('Both cache and network failed: "'+a.join('", "')+'"')):s=!0},f=function(e){e instanceof Response?r(e):u("No result returned")};o.fetchAndCache(e.clone(),n).then(f,u),i(e,t,n).then(f,u)})}var o=e("../helpers"),i=e("./cacheOnly");t.exports=r},{"../helpers":1,"./cacheOnly":8}],10:[function(e,t,n){t.exports={networkOnly:e("./networkOnly"),networkFirst:e("./networkFirst"),cacheOnly:e("./cacheOnly"),cacheFirst:e("./cacheFirst"),fastest:e("./fastest")}},{"./cacheFirst":7,"./cacheOnly":8,"./fastest":9,"./networkFirst":11,"./networkOnly":12}],11:[function(e,t,n){"use strict";function r(e,t,n){n=n||{};var r=n.successResponses||o.successResponses,c=n.networkTimeoutSeconds||o.networkTimeoutSeconds;return i.debug("Strategy: network first ["+e.url+"]",n),i.openCache(n).then(function(t){var s,a,u=[];if(c){var f=new Promise(function(r){s=setTimeout(function(){t.match(e).then(function(e){var t=n.cache||o.cache,c=Date.now(),s=t.maxAgeSeconds;i.isResponseFresh(e,s,c)&&r(e)})},1e3*c)});u.push(f)}var h=i.fetchAndCache(e,n).then(function(e){if(s&&clearTimeout(s),r.test(e.status))return e;throw i.debug("Response was an HTTP error: "+e.statusText,n),a=e,new Error("Bad response")}).catch(function(r){return i.debug("Network or response error, fallback to cache ["+e.url+"]",n),t.match(e).then(function(e){if(e)return e;if(a)return a;throw r})});return u.push(h),Promise.race(u)})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],12:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: network only ["+e.url+"]",n),fetch(e)}var o=e("../helpers");t.exports=r},{"../helpers":1}],13:[function(e,t,n){"use strict";var r=e("./options"),o=e("./router"),i=e("./helpers"),c=e("./strategies"),s=e("./listeners");i.debug("Service Worker Toolbox is loading"),self.addEventListener("install",s.installListener),self.addEventListener("activate",s.activateListener),self.addEventListener("fetch",s.fetchListener),t.exports={networkOnly:c.networkOnly,networkFirst:c.networkFirst,cacheOnly:c.cacheOnly,cacheFirst:c.cacheFirst,fastest:c.fastest,router:o,options:r,cache:i.cache,uncache:i.uncache,precache:i.precache}},{"./helpers":1,"./listeners":3,"./options":4,"./router":6,"./strategies":10}],14:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],15:[function(e,t,n){function r(e,t){for(var n,r=[],o=0,i=0,c="",s=t&&t.delimiter||"/";null!=(n=x.exec(e));){var f=n[0],h=n[1],p=n.index;if(c+=e.slice(i,p),i=p+f.length,h)c+=h[1];else{var l=e[i],d=n[2],m=n[3],g=n[4],v=n[5],w=n[6],y=n[7];c&&(r.push(c),c="");var b=null!=d&&null!=l&&l!==d,E="+"===w||"*"===w,R="?"===w||"*"===w,k=n[2]||s,$=g||v;r.push({name:m||o++,prefix:d||"",delimiter:k,optional:R,repeat:E,partial:b,asterisk:!!y,pattern:$?u($):y?".*":"[^"+a(k)+"]+?"})}}return i=46||"Chrome"===n&&r>=50)||(Cache.prototype.addAll=function(e){function t(e){this.name="NetworkError",this.code=19,this.message=e}var n=this;return t.prototype=Object.create(Error.prototype),Promise.resolve().then(function(){if(arguments.length<1)throw new TypeError;return e=e.map(function(e){return e instanceof Request?e:String(e)}),Promise.all(e.map(function(e){"string"==typeof e&&(e=new Request(e));var n=new URL(e.url).protocol;if("http:"!==n&&"https:"!==n)throw new t("Invalid scheme");return fetch(e.clone())}))}).then(function(r){if(r.some(function(e){return!e.ok}))throw new t("Incorrect response status");return Promise.all(r.map(function(t,r){return n.put(e[r],t)}))}).then(function(){})},Cache.prototype.add=function(e){return this.addAll([e])})}()},{}]},{},[13])(13)}); 16 | //# sourceMappingURL=sw-toolbox.js.map 17 | -------------------------------------------------------------------------------- /www/data/bio-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/biol01.jpg", 4 | "title": "农业生物技术", 5 | "magCode": "BIOL" 6 | }, 7 | { 8 | "coverimg": "images/carousel/biol02.jpg", 9 | "title": "生物能源技术", 10 | "magCode": "BIOL" 11 | }, 12 | { 13 | "coverimg": "images/carousel/biol03.jpg", 14 | "title": "特色农业生物技术", 15 | "magCode": "BIOL" 16 | }, 17 | { 18 | "coverimg": "images/carousel/biol04.jpg", 19 | "title": "基因组育种", 20 | "magCode": "BIOL" 21 | }, 22 | { 23 | "coverimg": "images/carousel/biol05.jpg", 24 | "title": "食品生物技术", 25 | "magCode": "BIOL" 26 | } 27 | ] -------------------------------------------------------------------------------- /www/data/com-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/comp01.jpg", 4 | "title": "计算语言学", 5 | "magCode": "COMP" 6 | }, 7 | { 8 | "coverimg": "images/carousel/comp02.jpg", 9 | "title": "机器学习", 10 | "magCode": "COMP" 11 | }, 12 | { 13 | "coverimg": "images/carousel/comp03.jpg", 14 | "title": "云计算", 15 | "magCode": "COMP" 16 | }, 17 | { 18 | "coverimg": "images/carousel/comp04.jpg", 19 | "title": "互联网创新应用", 20 | "magCode": "COMP" 21 | }, 22 | { 23 | "coverimg": "images/carousel/comp05.jpg", 24 | "title": "移动计算", 25 | "magCode": "COMP" 26 | } 27 | ] -------------------------------------------------------------------------------- /www/data/eco-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/econ01.jpg", 4 | "title": "经济增长", 5 | "magCode": "ECON" 6 | }, 7 | { 8 | "coverimg": "images/carousel/econ02.jpg", 9 | "title": "绿色经济", 10 | "magCode": "ECON" 11 | }, 12 | { 13 | "coverimg": "images/carousel/econ03.jpg", 14 | "title": "网络经济", 15 | "magCode": "ECON" 16 | }, 17 | { 18 | "coverimg": "images/carousel/econ04.jpg", 19 | "title": "蓝海战略", 20 | "magCode": "ECON" 21 | }, 22 | { 23 | "coverimg": "images/carousel/econ05.jpg", 24 | "title": "电子商务市场", 25 | "magCode": "ECON" 26 | } 27 | ] -------------------------------------------------------------------------------- /www/data/latest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "coverimg": "images/carousel/latest01.jpg", 4 | "title": "民间文学", 5 | "magCode": "LITE" 6 | }, 7 | { 8 | "coverimg": "images/carousel/latest02.jpg", 9 | "title": "视觉传播", 10 | "magCode": "COAR" 11 | }, 12 | { 13 | "coverimg": "images/carousel/latest03.jpg", 14 | "title": "光量子器件及通信", 15 | "magCode": "COMM" 16 | }, 17 | { 18 | "coverimg": "images/carousel/latest04.jpg", 19 | "title": "营养管理", 20 | "magCode": "FOOD" 21 | }, 22 | { 23 | "coverimg": "images/carousel/latest05.jpg", 24 | "title": "晶体材料", 25 | "magCode": "MATE" 26 | } 27 | ] -------------------------------------------------------------------------------- /www/data/mag-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "magName": "经济学", 4 | "magCode": "ECON" 5 | }, 6 | { 7 | "magName": "生物技术", 8 | "magCode": "BIOL" 9 | }, 10 | { 11 | "magName": "计算机科技", 12 | "magCode": "COMP" 13 | } 14 | ] -------------------------------------------------------------------------------- /www/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/fonts/ionicons.eot -------------------------------------------------------------------------------- /www/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/fonts/ionicons.ttf -------------------------------------------------------------------------------- /www/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/fonts/ionicons.woff -------------------------------------------------------------------------------- /www/images/adam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/adam.jpg -------------------------------------------------------------------------------- /www/images/ben.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/ben.png -------------------------------------------------------------------------------- /www/images/bg-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/bg-book.png -------------------------------------------------------------------------------- /www/images/carousel/biol01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/biol01.jpg -------------------------------------------------------------------------------- /www/images/carousel/biol02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/biol02.jpg -------------------------------------------------------------------------------- /www/images/carousel/biol03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/biol03.jpg -------------------------------------------------------------------------------- /www/images/carousel/biol04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/biol04.jpg -------------------------------------------------------------------------------- /www/images/carousel/biol05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/biol05.jpg -------------------------------------------------------------------------------- /www/images/carousel/comp01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/comp01.jpg -------------------------------------------------------------------------------- /www/images/carousel/comp02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/comp02.jpg -------------------------------------------------------------------------------- /www/images/carousel/comp03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/comp03.jpg -------------------------------------------------------------------------------- /www/images/carousel/comp04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/comp04.jpg -------------------------------------------------------------------------------- /www/images/carousel/comp05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/comp05.jpg -------------------------------------------------------------------------------- /www/images/carousel/econ01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/econ01.jpg -------------------------------------------------------------------------------- /www/images/carousel/econ02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/econ02.jpg -------------------------------------------------------------------------------- /www/images/carousel/econ03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/econ03.jpg -------------------------------------------------------------------------------- /www/images/carousel/econ04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/econ04.jpg -------------------------------------------------------------------------------- /www/images/carousel/econ05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/econ05.jpg -------------------------------------------------------------------------------- /www/images/carousel/latest01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/latest01.jpg -------------------------------------------------------------------------------- /www/images/carousel/latest02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/latest02.jpg -------------------------------------------------------------------------------- /www/images/carousel/latest03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/latest03.jpg -------------------------------------------------------------------------------- /www/images/carousel/latest04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/latest04.jpg -------------------------------------------------------------------------------- /www/images/carousel/latest05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/carousel/latest05.jpg -------------------------------------------------------------------------------- /www/images/icon-mp3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/icon-mp3.png -------------------------------------------------------------------------------- /www/images/ionic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/ionic.png -------------------------------------------------------------------------------- /www/images/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/max.png -------------------------------------------------------------------------------- /www/images/mike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/mike.png -------------------------------------------------------------------------------- /www/images/perry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/perry.png -------------------------------------------------------------------------------- /www/images/play-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/play-btn.png -------------------------------------------------------------------------------- /www/images/post-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/post-bg.gif -------------------------------------------------------------------------------- /www/images/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnnynode/ionic-samples/af40fdd6dfa5d47e8f5d20d6e99e81e23a7b9ad0/www/images/transparent.gif -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /www/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic", 3 | "short_name": "Ionic", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "assets/imgs/logo.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }], 11 | "background_color": "#4e8ef7", 12 | "theme_color": "#4e8ef7" 13 | } -------------------------------------------------------------------------------- /www/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechromelabs.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 7 | 'use strict'; 8 | importScripts('./build/sw-toolbox.js'); 9 | 10 | self.toolbox.options.cache = { 11 | name: 'ionic-cache' 12 | }; 13 | 14 | // pre-cache our key assets 15 | self.toolbox.precache( 16 | [ 17 | './build/main.js', 18 | './build/vendor.js', 19 | './build/main.css', 20 | './build/polyfills.js', 21 | 'index.html', 22 | 'manifest.json' 23 | ] 24 | ); 25 | 26 | // dynamically cache any other local assets 27 | self.toolbox.router.any('/*', self.toolbox.fastest); 28 | 29 | // for any other requests go to the network, cache, 30 | // and then only use that cached resource if your user goes offline 31 | self.toolbox.router.default = self.toolbox.networkFirst; 32 | --------------------------------------------------------------------------------