导航页的开发--手机web app开发笔记
好了,的所有的基础知识已经准备完毕了,现在开始制作引导页。这个引导页需要一个html文件,js文件,一个css文件。在hbuilderx中根目录下添加“guid.html”,在js文件夹添加“myth.js”,在css文件夹下添加“myth.css”。
一、myth.js文件
该文件是个插件,对常用的操作进行了封装,本章节主要把该文件的框架搭建出来,随着开发的深入,会不断的完善这个js文件,最后它会成为一个丰富的插件,一遍以后使用。
(一)基本框架
; //javascript 弱语法的特点,如果前面刚好有个函数没有以";"结尾,那么可能会有语法错误 var myth = (function(selector) { 'use strict'; var _myth = function(selector) { }; _myth.version = 'myth 1.0'; return _myth; })(document);
上述代码就是基本的插件代码,前面的分号,可以解决插件与其它js合并时,别的代码可能会产生的错误问题。
“(function(){})()”这个结构表示立即执行第一个小括号内的函数;第二个小括号中的“document”作为参数传递给第一个小括号内的函数。
'use strict';
这行代码表示严格模式,顾名思义,严格模式就是使得 javascript 在更严格的条件下运行,有助于更规范的开发。如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常。如果在运行期出现了违反严格模式的代码,则抛出执行异常。
二、myth.css文件
@charset "utf-8"; html { color: #333; background:#fff; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; text-rendering: optimizelegibility; } /* 统一内外边距*/ body, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea,
p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer,
header, menu, nav, section { margin: 0; padding: 0; }
三、index.html文件
首先在默认文档index.html中,填写代码实现:如果第一次启动将进入启动页“guid.html”,如果第二次启动直接进入程序主界面。其实这里的主界面就是“index.html”,的实现原理是这样的,webapp启动时,启动页面不需要自动关闭,等待的主界面“index.html”逻辑顺序,数据执行完毕,如果第一次启动在“guid.html”关闭webapp启动页面,如果不是第一次启动在“index.html”关闭webapp启动页面。
第一步:“manifest.json”可视化界面关掉“自动关闭启动界面”,如图4-1所示。
图4-1 启动界面设置
第二步:myth.js代码补充。
; //javascript 弱语法的特点,如果前面刚好有个函数没有以";"结尾,那么可能会有语法错误 var myth = (function(selector) { 'use strict'; var _myth = function(selector) { //如果默认参数不设置,自动赋值document if (!selector) { selector = document; } //获取selector数据类型,代码后面序号1有详细用法解释 var selectortype = typeof(selector); //根据selector数据类型,进行同操作,代码后面序号2有详细用法解释 switch (selectortype) { case 'string'://如果是字符串类型,使用queryselectorall获取selector对象,结果记录到reobj内 var doms = document.queryselectorall(selector);//通过该方法查找hmtl中select对象,代码后面序号2有详细用法解释 //reobj是个数据对象目前设置两个属性dom这个是javascript数据对象,length表示doms对象数量 var reobj = { dom: doms, length: doms.length }; break; case 'object'://如果是object类型,结果直接记录到reobj内 var reobj = { dom: [selector], length: 1 }; break; default://除了上述两种类型外,返回null对象 return null; } reobj.__proto__ = mythextends; //__proto__:是一个对象拥有的内置属性,是js内部使用寻找原型链的属性。可以理解为它是一个指针,
//用于指向创建它的函数对象的原型对象prototype(即构造函数的prototype),简单理解为“为reobj
//添加了一些扩展属性,myth(selector)选择对象后,可以进一步执行mythextends中的方法。 return reobj; };
//myth(selector)对象的扩展方法 var mythextends = { /* dom 元素遍历 */ each: function(callback) { if (!callback) { return; } for (var i = 0; i < this.length; i++) { this.dom[i].index = i; callback(this.dom[i]);//返回每一个dom对象 } }, setwidth: function(swidth) {//设置myth(selector)对象宽度 this.dom[0].style.width =swidth; }, redwidth: function() {//获取myth(selector)对象宽度 return this.dom[0].offsetwidth; }, setheight: function(sheight) {//设置myth(selector)对象高度 this.dom[0].style.height =sheight; }, redheight: function() {//获取myth(selector)对象高度 return this.dom[0].offsetheight; } } _myth.version = 'myth 1.0';//设置版本 _myth.plusready = function(callback) {//plusready是html5+ api,对这个方法进行了封装,以便调用,代码后面序号3有详细用法解释 document.addeventlistener('plusready', function() { if (callback) { callback(); } }); }; _myth.readstorage = function(key) {//读取本地数据 代码后面序号4有详细用法解释 return plus.storage.getitem(key) } _myth.wirtestorage = function(key, value) {//获取本地数据 plus.storage.setitem(key, value); } _myth.open = function(winname, styles, extras) {//打开新界面。 if (!window.plus) {//window.plus不为空,则替换当前网址 location.href = winname; return; } if (!styles) {//窗口样式为空,进行初始设置 styles = {}; } var w = this.create(winname, styles, extras);//创建新窗口,并显示。 plus.webview.show(w, 'slide-in-right'); return w; }; _myth.close = function(wid) {//关闭id为“wid”的窗口 if (typeof(wid) == "undefined") { plus.webview.currentwebview().close();//关闭当前窗口 } else { var w = plus.webview.getwebviewbyid(wid); if (w) { w.close(); } } }; _myth.create = function(winname, styles, extras) {//创建新窗口 if (typeof(styles) == "undefined") { styles = {}; } if (typeof(extras) == "undefined") { extras = {}; } if (!styles.zindex) { styles.zindex = 10; } var w = plus.webview.getwebviewbyid(winname);//获取id为“winname”的窗口 if (w) { return w; } w = plus.webview.create(winname, winname, styles, extras);//创建窗口 return w; }; _myth.wininfo = function() {//获取手机屏幕大小信息 var wininfo = {//窗口基本信息,包括高度,宽度,纵向滚动距离 height: 0, width: 0, scrolltop: 0 }; if (window.innerheight) {//如果获取到浏览器窗口的视口的高度,则赋值给wininfo.height wininfo.height = window.innerheight; } else if ((document.body) && (document.body.clientheight)) {//获取不到浏览器的窗口的高度,能获取到到body则获取body高度,进行赋值操作。 wininfo.height = document.body.clientheight; } if (window.innerwidth) {//如果获取到浏览器窗口的视口的宽度,,则赋值给wininfo.width wininfo.width = window.innerwidth; } else if ((document.body) && (document.body.clientwidth)) {//获取不到浏览器的窗口的高度,能获取到到body则获取body宽度,进行赋值操作。 wininfo.width = document.body.clientwidth; } if (document.documentelement && document.documentelement.scrolltop) {//获取纵向滚动距离 wininfo.scrolltop = document.documentelement.scrolltop; } else if (document.body) { wininfo.scrolltop = document.body.scrolltop; } return wininfo; }; return _myth; })(document);
1.typeof用法详解:
typeof是一个运算符,typeof(表达式)表示对表达式做运算,情况如表4-1所示。
序号 |
返回值 |
说明 |
1 |
'undefined' |
未定义的变量或值 |
2 |
'boolean' |
布尔类型的变量或值 |
3 |
'string' |
字符串类型的变量或值 |
4 |
'number' |
数字类型的变量或值 |
5 |
'object' |
对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理) |
6 |
'function' |
函数类型的变量或值 |
表4-1typeof返回数值类型
2.switch用法详解
switch 语句用于基于不同条件执行不同动作。语法结构如下:
switch(表达式n) { case 1: 代码块 break; case 2: 代码块 break; default: 默认代码块 } |
工作原理:首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行,其它不执行, break直接跳出switch。
3.plusready用法详解
plusready是html5+ api,在webapp开发中,若要使用html5+扩展api,必须等plusready事件发生后才能正常使用。
为了保证html5扩展api的有效调用,页面加载扩展api完成后会触发此事件。 通常应该在页面开始加载时监听此事件,当此事件触发后,就可以安全的调用html5扩展api。 如果应用使用多页面,每个都会收到此事件。
// 监听plusready事件 document.addeventlistener("plusready", function(){ // 扩展api加载完毕,现在可以正常调用扩展api // ...... }, false); |
4.storage用法详解
storage模块管理应用本地数据存储区,用于应用数据的保存和读取,主要方法如表4-2所示。
序号 |
方法 |
说明 |
举例 |
1 |
getlength |
获取应用存储区中保存的键值对的个数 |
plus.storage.getlength(); |
2 |
getitem |
通过键(key)检索获取应用存储的值。key: ( domstring ) 必选 |
plus.storage.getitem(key); |
3 |
setitem
|
修改或添加键值(key-value)对数据到应用数据存储中。key: ( domstring ) 必选 存储的键值 value: domstring ) 必选 存储的内容 |
void plus.storage.setitem(key, value); |
4 |
removeitem
|
通过key值删除键值对存储的数据 |
void plus.storage.removeitem(key); |
5 |
clear
|
清除应用所有的键值对存储数据 |
void plus.storage.clear(); |
表4-2 storage用法介绍
第三步:“index.html”代码修改。在默认文档的基础上添加html代码,javascript代码完成需要的功能,具体代码如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title></title> <link rel="stylesheet" type="text/css" href="css/myth.css"/> <script src="js/myth.js"></script> <script type="text/javascript"> myth.plusready(function() { var isguid = myth.readstorage('isguid');//获取本地存储key为"isguid"的数值 if (isguid) {//如果存在说明不是第一次启动 myth.closestartpage();//关闭启动页 } else {//不存在,说明不是第一次启动 myth.open('guid.html', {background: 'transparent'}, {});//跳转到引导页 } }) </script> </head> <body> 编程之路 </body> </html>
四、guid.html
本页面实现导航页,共四张图片,向做滑动,切换。最后一张向做滑动进入webapp住界面,单击按钮跳过,进入webapp住界面。最终效果如图4-2所示。
图4-2 导航页图片切换效果
第一步:对myth.css文件补充。
/* 设置全屏 */
.fullscreen{
width:100%; height:100%; position: fixed; margin: 0px; top: 0px;left: 0px;
}
上述代码对页面容器进行全屏设置,position 属性规定元素的定位类型,取值如表4-3所示。
序号 |
取值 |
说明 |
1 |
absolute |
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。 |
2 |
fixed |
生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过"left", "top", "right" 以及 "bottom" 属性进行规定。 |
3 |
relative |
生成相对定位的元素,相对于其正常位置进行定位。因此,"left:20"会向元素的 left 位置添加 20 像素。 |
4 |
static |
默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。 |
5 |
inherit |
规定应该从父元素继承 position 属性的值。 |
表4-3 css元素定位
第二步:guid.html中html代码补充。
<div class="fullscreen"> <!-- 定义一个div容器,全屏 --> <div class="guid-items" id="picbox"> <!-- 定义一个存放图片容器,存放四张图片 --> <img src="img/guid1.jpg" id="pic1" /><img src="img/guid2.jpg" id="pic2" /><img src="img/guid3.jpg" id="pic3" />
<img src="img/guid4.jpg" id="pic4" /> </div> </div> <div id="gotubutton" onclick="closeguid()">跳过</div> <!-- 定义一个跳过按钮,单击跳出导航进入webapp主界面 -->
第三步:guid.html中引入myth.css,并补充样式。
<link rel="stylesheet" type="text/css" href="css/myth.css" /> <style type="text/css"> .guid-items { /* 图片容器样式 */ position: fixed;/* 生成绝对定位的元素,相对于浏览器窗口进行定位 */ height: 100%;/* 容易高度100%,全屏 */ } .guid-items img {/* 定义容器中的图片属性,所有外边距0,内边距同样为0 */ margin: 0px; padding: 0px; } #gotubutton {/* 定义跳过按钮样式,宽50像素,,, */ width: 50px;/* 宽50像素 */ height: 50px;/* 高50像素 */ position: fixed;/* 相对于浏览器窗口绝对定位 */ z-index: 10000;/* 堆叠顺序为10000,也就是让该按钮要浮于图片上方,可以让用户看到 */ top: 50px;/* 距离上方50像素 */ right: 20px;/* 距离右方20像素,也就是右上角显示 */ background: #ff6600;/* 按钮背景色 */ text-align: center;/* 按钮中文字水平居中对齐 */ border-radius: 50px;/* 圆形按钮设置 */ line-height: 50px;/* 行间距为50像素 */
color: #ffffff;/* 按钮中文字颜色 */ }
</style>
第四步:guid.html中引入myth.js,并编写js代码。
<script src="js/myth.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var wininfo = myth.wininfo();//获取手机信息 var screenwidth = wininfo.width;//宽度 var guidbox = myth("#picbox");//获取id为"picbox"对象 guidbox.setwidth("400%");//设置id为"picbox"对象宽度400%,也就是4个屏幕的宽度,4张图片正好一排显示 var zguidbox = guidbox.dom[0];//获取javascript对象 myth("#picbox img").each(function(cobj) {//获取id为"picbox"对象下面的所有图片,并循环 myth(cobj).setwidth('25%');//设置每张图片宽度为25%,正好是1个屏幕大小 }) var currentimg = 1;//当前屏幕显示图片序号 var startx, endx;//定义开始手指按住屏幕x轴坐标,和手指离开屏幕x轴坐标 var ispress = false;//判断手指是否按住屏幕 var gundong=0;//手指按住屏幕后,滑动距离 zguidbox.addeventlistener("touchstart", function(e) {//监听手指按住屏幕事件 ispress = true;//手指按钮变量设为true startx = e.touches[0].clientx;//记录手指按住坐标 }); zguidbox.addeventlistener("touchmove", function(e) {//监听手指滑动事件 if (ispress) {//判断是否按住住屏幕 endx = e.touches[0].clientx;//记录滑动最后坐标 gundong = startx - endx;//计算滑动距离 if (gundong < 0) return;//滑动距离小于0,说明是向右滑动,不进行任何操作,直接退出 var juli = -1 * (currentimg - 1) * screenwidth - gundong;//向左滑动时,计算图片需要滑动的距离 zguidbox.style.transform = 'translate3d(' + juli + 'px, 0px, 0px)';//图片相应滑动 } }); zguidbox.addeventlistener("touchend", function(e) {//监听手指离开屏幕事件 if (gundong <= 0) return;//如果距离向左滑动,或未滑动直接退出 if (gundong > 0) {//如果向右滑动 var juli = -1 * currentimg * screenwidth;//计算滑动到相应序号图片的距离 zguidbox.style.transform = 'translate3d(' + juli + 'px, 0px, 0px)';//图片滑动到相应图片 zguidbox.style.transition = '300ms';//添加滑动时间,手指离开屏幕后,图片300毫秒,滑动到指定距离 currentimg++;//当前显示图片序号加一 if (currentimg == 5) {//如果是最后一张图片滑过 myth.wirtestorage("isguid", "true");//本地存储key为"isguid"设置为true,说明已经第一次启动程序 myth.close();//退出引导页 } } ispress = false;//手指按住屏幕变量设置为false }); function closeguid() { myth.wirtestorage('isguid',"true");//本地存储key为"isguid"设置为true,说明已经第一次启动程序 myth.close();//退出引导页 var isguid = myth.readstorage('isguid');//获取本地存储key为"isguid"的数值 console.log(isguid); } </script>
五、调试
导航页,到目前为止已经全部编写完毕,下一步这个过程非常重要,就是对代码进行调试。在hbuilderx中调试代码有两种途径,一是真机调试,另一种就是模拟器调试,下面分别学习一下。
(一)真机调试
讲的手机与电脑连接,连接成功后,在hbuilderx状态栏中显示手机已连接上电脑,如图4-3所示。
图4-3 手机连接电脑状态显示
在hbuilderx上方的工具条中点击运行按钮,即可在手机上运行,底部的控制台会有数据显示,如图4-4所示,如果有错误也会在此显示相关数据,根据提示进行修改即可。
图4-4 控制台数据
(二)模拟器调试
我用的是“夜神模拟器”,这个模拟器从网上安装下载即可。然后,在hbuilderx菜单栏中“运行”→“运行到手机或模拟器”→“android模拟器端口设置”,如图4-5所示。
图4-5 模拟器设置
在端口设置页面设置端口号“62001”即可,如图4-6所示,这样的模拟器调试页设置完毕。同样在在hbuilderx上方的工具条中点击运行按钮,即可在模拟器上运行,调试过程同真机。
图4-6 模拟器端口设置
常用的android模拟器的端口如表4-4所示:
模拟器名称 |
连接默认端口 |
夜神安卓模拟器夜神安卓模拟器 |
62001 |
逍遥安卓模拟器逍遥安卓模拟器 |
21503 |
bluestacks(蓝叠安卓模拟器) 雷电安卓模拟 |
5555 |
器雷电安卓模拟器 |
5555 |
天天安卓模拟器天天安卓模拟器 |
5037 |
网易mumu(安卓模拟器) |
7555 |
安卓模拟器大师安卓模拟器大师 |
54001 |
genymotion |
5555 |
表4-4 常用android模拟器端口列表
上一篇: 漫谈golang设计模式 简易工厂模式
下一篇: Python 【爬虫】
推荐阅读
-
默认文档解析--手机web app开发笔记(二)
-
Mobile Web开发基础之四--处理手机设备的横竖屏问题
-
JS解决移动web开发手机输入框弹出的问题
-
manifest.json 解析--手机web app开发笔记(三-2)
-
开发内嵌在 web,可能会遇到意想不到的 bug,所以你需要你能在手机上查看的控制台。
-
Java学习笔记-全栈-web开发-22-后端程序员用的前端框架——layUI
-
iOS开发笔记 -- 实时上传用户的位置(APP被杀死的情况下也要能上传)
-
Beginning Spring学习笔记——第11章 使用Spring开发REST风格的Web服务
-
[书籍精读]《基于MVC的JavaScript Web富应用开发》精读笔记分享
-
SpringBoot的Web开发之WebSocket(广播式)笔记总结