移动WebApp开发记录

这段时间在做移动WebApp开发,基于PhoneGap+Jquery Mobile,遇到不少问题,下面进行部分总结。 1.webStorage有大小限制(5M),Chrome出现”QUOTA_EXCEEDED_ERR: DOM Exception 22″错误,极有可能因为webStorage缓存的问题。 2.localStorage只能存字符串,不能存对象。 3.Jquery的Html(str)函数会将str里的内容进行过滤,遇到显示有问题,可使用(“.show”)[0].innerHTML=str代替。 4.对于xml字符串,如果用jquery操作,需转换为xml对象,$.parseXML(source)。对于从接口返回的xml,Jquery可以设置指定返回xml对象。 5.Jquery Mobile在不同的页面切换,Android有明显的卡顿及闪屏感觉。 $.mobile.showPageLoadingMsg()不生效。 A1.Android有明显的卡顿及闪屏感觉,据说是因为其对CSS3支持不好。 A2.Jquery Mobile在不同的页面切换,需要Loading效果的可以试下以下代码: function w2mTransitionHandler( name, reverse, $to, $from ) { $(".ui-loader").css({"display": "block", "top": "252px !important" }); var deferred = new $.Deferred(), reverseClass = reverse ? " reverse" : "", viewportClass = "ui-mobile-viewport-transitioning viewport-" + name, doneFunc = function() { $to.add( $from ).removeClass( "out in reverse " + name ); if ( $from && $from[ 0 ] !== $to[ 0 ] ) { $from.removeClass( $.mobile.activePageClass ); } $to.parent().removeClass( viewportClass ); $(".ui-loader").css({ "display": "none" }); deferred.resolve( name, reverse, $to, $from ); }; $to.animationComplete( doneFunc ); $to.parent().addClass( viewportClass ); if ( $from ) { $from.addClass( name + " out" + reverseClass ); } $to.addClass( $.mobile.activePageClass + " " + name + " in" + reverseClass ); return deferred.promise(); } $.mobile.defaultTransitionHandler = w2mTransitionHandler; A3.$.mobile.showPageLoadingMsg()有时会不生效,考虑以下代码: $(":button").click(function(){ //position:fixed;top: 252px !important; display: block; $(".ui-loader").css({"top": "252 !important","position":"fixed"}); $(".ui-loader").show("normal", function () { var list = new ListData(channelid, num, channelname); list.getData(); if(list.list.length==0) { alert("已是最后一页"); } else { list.showData(); num++; } $(".ui-loader").hide("normal"); }); })

December 2, 2011 · 1 min · 166 words · jabin

悟透JavaScript笔记

原生闭包 function Person(firstName, lastName, age) { //私有变量: var _firstName = firstName; var _lastName = lastName; //公共变量: this.age = age; //方法: this.getName = function() { return(firstName + " " + lastName); }; this.SayHello = function() { alert("Hello, I'm " + firstName + " " + lastName); }; }; var BillGates = new Person("Bill", "Gates", 53); var SteveJobs = new Person("Steve", "Jobs", 53); BillGates.SayHello(); SteveJobs.SayHello(); alert(BillGates.getName() + " " + BillGates.age); alert(BillGates.firstName); //这里不能访问到私有变量 甘露模型 //定义类的语法甘露:Class() //最后一个参数是JSON表示的类定义 //如果参数数量大于1个,则第一个参数是基类 //第一个和最后一个之间参数,将来可表示类实现的接口 //返回值是类,类是一个构造函数 function Class() { var aDefine = arguments[arguments.length-1]; //最后一个参数是类定义 if(!aDefine) return; var aBase = arguments.length>1 ? arguments[0] : object; //解析基类 function prototype_(){}; //构造prototype的临时函数,用于挂接原型链 prototype_.prototype = aBase.prototype; //准备传递prototype var aPrototype = new prototype_(); //建立类要用的prototype for(var member in aDefine) //复制类定义到当前类的prototype if(member!="Create") //构造函数不用复制 aPrototype[member] = aDefine[member]; //根据是否继承特殊属性和性能情况,可分别注释掉下列的语句 if(aDefine.toString != Object.prototype.toString) aPrototype.toString = aDefine.toString; if(aDefine.toLocaleString != Object.prototype.toLocaleString) aPrototype.toLocaleString = aDefine.toLocaleString; if(aDefine.valueOf != Object.prototype.valueOf) aPrototype.valueOf = aDefine.valueOf; if(aDefine.Create) //若有构造函数 var aType = aDefine.Create //类型即为该构造函数 else //否则为默认构造函数 aType = function() { this.base.apply(this, arguments); //调用基类构造函数 }; aType.prototype = aPrototype; //设置类(构造函数)的prototype aType.Base = aBase; //设置类型关系,便于追溯继承关系 aType.prototype.Type = aType; //为本类对象扩展一个Type属性 return aType; //返回构造函数作为类 }; //根类object定义: function object(){} //定义小写的object根类,用于实现最基础的方法等 object.prototype.isA = function(aType) //判断对象是否属于某类型 { var self = this.Type; while(self) { if(self == aType) return true; self = self.Base; }; return false; }; object.prototype.base = function() //调用基类构造函数 { var Base = this.Type.Base; //获取当前对象的基类 if(!Base.Base) //若基类已没有基类 Base.apply(this, arguments) //则直接调用基类构造函数 else //若基类还有基类 { this.base = MakeBase(Base); //先覆写this.base Base.apply(this, arguments); //再调用基类构造函数 delete this.base; //删除覆写的base属性 }; function MakeBase(Type) //包装基类构造函数 { var Base = Type.Base; if(!Base.Base) return Base; //基类已无基类,就无需包装 return function() //包装为引用临时变量Base的闭包函数 { this.base = MakeBase(Base); //先覆写this.base Base.apply(this, arguments); //再调用基类构造函数 }; }; }; //语法甘露的应用效果: var Person = Class //默认派生自object基本类 ({ Create: function(name, age) { this.base(); //调用上层构造函数 this.name = name; this.age = age; }, SayHello: function() { alert("Hello, I'm " + this.name + ", " + this.age + " years old."); }, toString: function() //覆写toString方法 { return this.name; } }); var Employee = Class(Person, //派生自Person类 { Create: function(name, age, salary) { this.base(name, age); //调用基类的构造函数 this.salary = salary; }, ShowMeTheMoney: function() { alert(this + " $" + this.salary); //这里直接引用this将隐式调用toString() } }); var BillGates = new Person("Bill Gates", 53); var SteveJobs = new Employee("Steve Jobs", 53, 1234); alert(BillGates); //这里将隐式调用覆写后的toString()方法 BillGates.SayHello(); SteveJobs.SayHello(); SteveJobs.ShowMeTheMoney(); var LittleBill = new BillGates.Type("Little Bill", 6); //用BillGate的类型建LittleBill LittleBill.SayHello(); alert(BillGates.isA(Person)); //true alert(BillGates.isA(Employee)); //false alert(SteveJobs.isA(Person)); //true 参考资料: ...

November 8, 2011 · 2 min · 371 words · jabin

HTML5笔记-地理定位

地理定位(Geolocation)是一个可以获取到客户端经纬度等地理位置信息的API。 API本身是不知道客户端地理信息的,常见的地理位置信息来源有全球定位系统(GPS)和从网络信号中推断出的地理信息(如IP地址, RFID, WIFI, 蓝牙MAC地址, GSM/CDMA手机id,以及用户输入的信息 ) 先来了解下Geolocation API: //返回地理定位对象 var geo = navigator.geolocation; /* *方法,获取当前客户端地理位置 *有三个参数可以用 *successCallback:必需,函数,获取成功后的回调函数 *errorCallback:可选,函数,失败时的回调函数 *options:可选,对象字面量,有三个值可设定: * enableHighAccuracy:是否启用高精度设备(高精度设备包含但不局限于前面所提到的 GPS 和 WIFI) * maximumAge:数值,如果将其定义为负数或者未定义,会重设为0 * timeout:数值,请求获取地理信息时的超时时间,如果将其定义为负数会重设为0,如果未定义则不启用超时判断 */ geo.getCurrentPosition(successCallback,errorCallback,options); /* *方法,持续监控当前客户端地理位置(实时) *返回该watchPosition的id*参数同getCurrentPosition */ var watchGEO = geo.watchPosition(successCallback,errorCallback,options); /*方法,结束指定ID的watchPosition*/ geo.clearWatch(watchId); 使用地理定位API需要获得用户的许可,如果没有,会执行errorCallback; watchPosition的successCallback只有在获取到的实时地理位置和之前有较大不同时才会执行; getCurrentPosition和watchPosition的successCallback都有一个position参数,它包含有详细的地理信息如经纬度: geo.getCurrentPosition(function (pos) {//成功获取时执行 var coord = pos.coords, //坐标detail accuracy = coord.accuracy, //精准度,单位为米 latitude = coord.latitude, //纬度 longitude = coord.longitude, //经度 altitudeAccuracy = coord.altitudeAccuracy, //高度精确度,单位为米 heading = coord.heading, //移动的方向 speed = coord.speed; //速度 showLocationInfo(coord,‘map’); //显示坐标信息 showMap(coord,‘map’); //显示google地图 }, function (error) {//获取失败时执行 alert(‘error:’+error.message+‘\n\n无法获得您的地理位置:’); }); 取到经纬度就可以利用各map服务商的app来显示地图,如google map

November 3, 2011 · 1 min · 88 words · jabin

HTML5笔记-离线应用

为了能够让用户在离线状态下继续访问 Web 应用,需要一种方式来指明应用程序离线工作时所需的资源文件。这样,浏览器才能在在线状态时,把这些文件缓存到本地。此后,当用户离线访问应用程序时,这些资源文件会自动加载,从而让用户正常使用。HTML5 中,通过 cache manifest 文件指明需要缓存的资源,并支持自动和手动两种缓存更新方式。 开发者需要提供一个 cache manifest 文件。这个文件中列出了所有需要在离线状态下使用的资源,浏览器会把这些资源缓存到本地。 我们通过 W3C 提供的示例来说明。Clock Web 应用由三个文件“clock.html”、“clock.css”和“clock.js”组成。 <!-- clock.html --> < !DOCTYPE HTML> <html> <head> <title>Clock</title> <script src="clock.js"></script> <link rel="stylesheet" href="clock.css"> </link></head> <body> <p>The time is: <output id="clock"></output></p> </body> </html> /* clock.css */ output { font: 2em sans-serif; } /* clock.js */ setTimeout(function () { document.getElementById('clock').value = new Date(); }, 1000); 当用户在离线状态下访问“clock.html”时,页面将无法展现。为了支持离线访问,开发者必须添加 cache manifest 文件,指明需要缓存的资源。这个例子中的 cache manifest 文件为“clock.manifest”,它声明了 3 个需要缓存的资源文件“clock.html”、“clock.css”和“clock.js”。 clock.manifest 代码 ...

November 3, 2011 · 2 min · 263 words · jabin

HTML5笔记-web本地存储

Web Storage就是放大版的cookie——提供了比cookie更大的本地存储,并且不会向服务器发出请求,并提供了一些API。总之本地存储能更专业地处理本地数据。 可以像对象字面量那样使用Web Storage: localStorage.fresh = "vfresh.org"; //设置一个键值 var a = localStorage.fresh; //获取键值 delete localStorage['fresh'] //删除键值 或者使用它的API: //清空storage localStorage.clear(); //设置一个键值 localStorage.setItem("fresh","vfresh.org"); //获取一个键值 localStorage.getItem("fresh"); //return "vfresh.org" //获取指定下标的键的名称(如同Array) localStorage.key(0); //return "fresh" //删除一个键值 localStorage.removeItem("fresh"); 字面量方式比API更高效,也更方便,所以你懂的。 localStorage是永久性的保存,而sessionStorage在浏览器窗口关闭后就没有了(相当于Expire=0的cookie)。 支持浏览器:IE 8+, Firefox 3.0+, Safari 4.0+, Chrome 4.0+, Opera 10.5+

November 3, 2011 · 1 min · 43 words · jabin