HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

XHRHTTPREQUEST的一个坑

ajax

我使用xhrhttprequest发送POST请求,按照官网说得在调用send方法的时候传送data参数,后台死活取不到值,后面测试一看才知道传送的data参数是在作为body数据传送过去,后台接收的post参数为空,raw参数才是我们传送的值
后来改为mui.ajax就没问题了.....
特记录在这里,免得大家入坑

继续阅读 »

我使用xhrhttprequest发送POST请求,按照官网说得在调用send方法的时候传送data参数,后台死活取不到值,后面测试一看才知道传送的data参数是在作为body数据传送过去,后台接收的post参数为空,raw参数才是我们传送的值
后来改为mui.ajax就没问题了.....
特记录在这里,免得大家入坑

收起阅读 »

关于二级页面返回后刷新一级页面的实践

返回刷新 mui

var taskList = plus.webview.getWebviewById('tasklist');
taskList.reload();
mui.back();

1、上面是我根据官方的提示方法,以及问答社区朋友的回答,得到的返回刷新页面的方法。

2、具体实现方法是,把以上代码放到触发返回刷新事件的元素上

document.getElementById("btn").addEventListener("tap", function() {  
       var taskList = plus.webview.getWebviewById('tasklist');  
       taskList.reload();  
       mui.back();  
}

3、getWebviewById('tasklist');中的tasklist即为要刷新的页面的id,但是这个id从何而来呢?

4、其实除了入口页面,其他页面都是可以通过openwindow的时候追加id的,也就是说是通过要刷新的页面的上一个页面得来。

mui.openWindow({  
        url: 'my-task-list.html',  
        id: 'tasklist',  
}

5、我在处理返回刷新的时候在getWebviewById这里卡了很久,记录下来,以备查阅。

继续阅读 »

var taskList = plus.webview.getWebviewById('tasklist');
taskList.reload();
mui.back();

1、上面是我根据官方的提示方法,以及问答社区朋友的回答,得到的返回刷新页面的方法。

2、具体实现方法是,把以上代码放到触发返回刷新事件的元素上

document.getElementById("btn").addEventListener("tap", function() {  
       var taskList = plus.webview.getWebviewById('tasklist');  
       taskList.reload();  
       mui.back();  
}

3、getWebviewById('tasklist');中的tasklist即为要刷新的页面的id,但是这个id从何而来呢?

4、其实除了入口页面,其他页面都是可以通过openwindow的时候追加id的,也就是说是通过要刷新的页面的上一个页面得来。

mui.openWindow({  
        url: 'my-task-list.html',  
        id: 'tasklist',  
}

5、我在处理返回刷新的时候在getWebviewById这里卡了很久,记录下来,以备查阅。

收起阅读 »

每日一课 跨平台APP开发精品公开课

mui HBuilder

腾讯课堂专业IT培训,每天都有免费公开课,想学习的同学们来听课,可以收藏课表,HTML+CSS课程,JavaScript课程,跨平台APP开发课程,全天三个时间段免费直播,老师在线交流, 马上学习 >>>跨平台app开发精品课

继续阅读 »

腾讯课堂专业IT培训,每天都有免费公开课,想学习的同学们来听课,可以收藏课表,HTML+CSS课程,JavaScript课程,跨平台APP开发课程,全天三个时间段免费直播,老师在线交流, 马上学习 >>>跨平台app开发精品课

收起阅读 »

ajax像jq一样通过表单序列化方式提交表单

mui

      mui.ajax('url', {  
            data: $("#form").serialize(),  
            dataType: 'json',  
            type: 'post',  
            timeout: 10000,  
            success: function(data) {  
                //成功的操作  
            },  
            error: function(xhr, type, errorThrown) {  
                //失败的操作  
            }  
      });  

没错,就是设置data的值为$("#form").serialize(),不过这样要引入jquery,好像官方不太建议直接引入jq,不知道有没有更好的方法去序列化一个表单

继续阅读 »

      mui.ajax('url', {  
            data: $("#form").serialize(),  
            dataType: 'json',  
            type: 'post',  
            timeout: 10000,  
            success: function(data) {  
                //成功的操作  
            },  
            error: function(xhr, type, errorThrown) {  
                //失败的操作  
            }  
      });  

没错,就是设置data的值为$("#form").serialize(),不过这样要引入jquery,好像官方不太建议直接引入jq,不知道有没有更好的方法去序列化一个表单

收起阅读 »

闹铃提醒

Broadcast Native.JS 广播

项目需要,做了一个闹铃提醒的例子。


<!DOCTYPE html>  
<html>  

    <head>  
        <meta charset="utf-8">  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <title>TTimer</title>  
        <script src="js/mui.min.js"></script>  
        <link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet" />  
    </head>  

    <body style="padding: 40px;">  
        <button id="alarm"> 插入闹铃</button>  
    </body>  
    <script type="text/javascript" charset="utf-8">  
        mui.init();  
        mui.plusReady(function() {  
            //  
            mui("body").on('tap', 'button', function(event) {  
                var id = this.getAttribute('id');  
                if (id == "alarm") {  
                    addAlarm();  
                }  
            });  
            var main = plus.android.runtimeMainActivity();  
            // 广播接收  
            var ALARM_RECEIVER = "alarm_receiver";  
            var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
                onReceive: function(context, intent) { //实现onReceiver回调函数  
                    plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                    //console.log(intent.getAction()); //获取action  
                    var txt = "接收到消息"   intent.getAction()   ": "   getCurTime();  
                    mui.toast(txt);  
                    pushMsg(txt);  
                    main.unregisterReceiver(receiver); //取消监听  
                }  
            });  
            //  
            function addAlarm() {  
                // --- 注册监听 start ---  
                var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
                var filter = new IntentFilter(ALARM_RECEIVER);  
                main.registerReceiver(receiver, filter);  
                // --- 注册监听 end ---  
                // --- 设置闹铃时间 start ---  
                var Calendar = plus.android.importClass('java.util.Calendar');  
                var calendar = Calendar.getInstance();  
                // 11点4分执行  
                //calendar.set(Calendar.HOUR_OF_DAY, 11);  
                //calendar.set(Calendar.MINUTE, 4);  
                //calendar.set(Calendar.SECOND, 0);  
                // 过5s 执行  
                calendar.setTimeInMillis(Date.parse(new Date()));  
                calendar.add(Calendar.SECOND, 5);  
                // --- 设置闹铃时间 end ---  
                // --- 设置闹铃 ---  
                var Intent = plus.android.importClass('android.content.Intent');  
                var intent = new Intent(ALARM_RECEIVER);  
                //  
                var PendingIntent = plus.android.importClass('android.app.PendingIntent');  
                var sender = PendingIntent.getBroadcast(main, 0, intent, 0);  
                //  
                var AlarmManager = plus.android.importClass("android.app.AlarmManager");  
                var Context = plus.android.importClass("android.content.Context");  
                var alarm = main.getSystemService(Context.ALARM_SERVICE);  
                // 一次    
                alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);  
                // 重复多次  
                //alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5 * 1000, sender);  
                mui.toast("设置闹铃5秒后提醒: "   getCurTime());  
            };  
            //  
            function pushMsg(content) {  
                var options = {  
                    "title": "闹铃提醒",  
                };  
                plus.push.createMessage(content, "alarm", options);  
            };  
            //  
            function getCurTime() {  
                var d = new Date();  
                return d.getFullYear()   "-"   (d.getMonth()   1)   "-"   d.getDate()   " "   d.getHours()   ":"   d.getMinutes()   ":"   d.getSeconds();  
            };  
        });  
    </script>  

</html>  
继续阅读 »

项目需要,做了一个闹铃提醒的例子。


<!DOCTYPE html>  
<html>  

    <head>  
        <meta charset="utf-8">  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <title>TTimer</title>  
        <script src="js/mui.min.js"></script>  
        <link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet" />  
    </head>  

    <body style="padding: 40px;">  
        <button id="alarm"> 插入闹铃</button>  
    </body>  
    <script type="text/javascript" charset="utf-8">  
        mui.init();  
        mui.plusReady(function() {  
            //  
            mui("body").on('tap', 'button', function(event) {  
                var id = this.getAttribute('id');  
                if (id == "alarm") {  
                    addAlarm();  
                }  
            });  
            var main = plus.android.runtimeMainActivity();  
            // 广播接收  
            var ALARM_RECEIVER = "alarm_receiver";  
            var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
                onReceive: function(context, intent) { //实现onReceiver回调函数  
                    plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                    //console.log(intent.getAction()); //获取action  
                    var txt = "接收到消息"   intent.getAction()   ": "   getCurTime();  
                    mui.toast(txt);  
                    pushMsg(txt);  
                    main.unregisterReceiver(receiver); //取消监听  
                }  
            });  
            //  
            function addAlarm() {  
                // --- 注册监听 start ---  
                var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
                var filter = new IntentFilter(ALARM_RECEIVER);  
                main.registerReceiver(receiver, filter);  
                // --- 注册监听 end ---  
                // --- 设置闹铃时间 start ---  
                var Calendar = plus.android.importClass('java.util.Calendar');  
                var calendar = Calendar.getInstance();  
                // 11点4分执行  
                //calendar.set(Calendar.HOUR_OF_DAY, 11);  
                //calendar.set(Calendar.MINUTE, 4);  
                //calendar.set(Calendar.SECOND, 0);  
                // 过5s 执行  
                calendar.setTimeInMillis(Date.parse(new Date()));  
                calendar.add(Calendar.SECOND, 5);  
                // --- 设置闹铃时间 end ---  
                // --- 设置闹铃 ---  
                var Intent = plus.android.importClass('android.content.Intent');  
                var intent = new Intent(ALARM_RECEIVER);  
                //  
                var PendingIntent = plus.android.importClass('android.app.PendingIntent');  
                var sender = PendingIntent.getBroadcast(main, 0, intent, 0);  
                //  
                var AlarmManager = plus.android.importClass("android.app.AlarmManager");  
                var Context = plus.android.importClass("android.content.Context");  
                var alarm = main.getSystemService(Context.ALARM_SERVICE);  
                // 一次    
                alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);  
                // 重复多次  
                //alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5 * 1000, sender);  
                mui.toast("设置闹铃5秒后提醒: "   getCurTime());  
            };  
            //  
            function pushMsg(content) {  
                var options = {  
                    "title": "闹铃提醒",  
                };  
                plus.push.createMessage(content, "alarm", options);  
            };  
            //  
            function getCurTime() {  
                var d = new Date();  
                return d.getFullYear()   "-"   (d.getMonth()   1)   "-"   d.getDate()   " "   d.getHours()   ":"   d.getMinutes()   ":"   d.getSeconds();  
            };  
        });  
    </script>  

</html>  
收起阅读 »

只要是Hbuilder大牛,就宠定你了!

国家软件创业实训中心孵化企业--上海比冲信息科技有限公司诚招Hbuilder工程师
工作地点:上海杨浦区五角场
待遇:6-12K
要求:至少1年Hbuilder开发经验或至少完成1个APP
霸气女王邀你入伙,一同寻宝!
点燃他们(球迷、彩迷)的荷尔蒙!

作品和简历请发到这里:ling.fu@foodietech.cn

继续阅读 »

国家软件创业实训中心孵化企业--上海比冲信息科技有限公司诚招Hbuilder工程师
工作地点:上海杨浦区五角场
待遇:6-12K
要求:至少1年Hbuilder开发经验或至少完成1个APP
霸气女王邀你入伙,一同寻宝!
点燃他们(球迷、彩迷)的荷尔蒙!

作品和简历请发到这里:ling.fu@foodietech.cn

收起阅读 »

关于HBuilder弹出“请查看...log文件”启动不了的解决办法。

启动

我在win10下面使用的HBuilder 7.0.0版本。
之前没觉得HB有什么不爽的,除了启动的时候有一丝丝慢的温柔感,但还是可以忍的。

直到刚才上班开电脑后启动HB时弹出“请查看xxxlog文件”时我就蒙毙了。

打开HB官网后发现有这个交流社区,搜索“HBuilder启动不了”后弹出好多贴,料到很多大小猿也遇到了这个问题。

看了几篇也没发现有什么好的解决方案。不过有一个网友提到了注册表,让我醍醐灌顶。

首先,启动不了时我第一选择是删除再解压原来的安装包,然并卵;
然后,更换安装根目录(原先在D盘,剪切至E盘),然并卵。
最后,愤然打开"WIN+R",输入“regedit”,进入注册表窗口,接着就兴高采烈的搜索“HBuilder”删除相应注册表条目,直至搜索不出来。

删完注册表,去茶水间倒杯咖啡,闻了一下,回到座位上打开HB的安装目录尝试再次启动。

OK,输入帐号密码,登录成功!!

不废话了,有这种情况的朋友赶紧跑注册表里倒腾去吧!

以上是我个人遇到的情况与解决方法,采纳前请慎重考虑。


建议工程根目录不要放在HB的安装目录,HB丢了不要紧再装一个,但你的工程丢了如果没有备份就该喊娘了!

个人网站:http://www.ipic.so

继续阅读 »

我在win10下面使用的HBuilder 7.0.0版本。
之前没觉得HB有什么不爽的,除了启动的时候有一丝丝慢的温柔感,但还是可以忍的。

直到刚才上班开电脑后启动HB时弹出“请查看xxxlog文件”时我就蒙毙了。

打开HB官网后发现有这个交流社区,搜索“HBuilder启动不了”后弹出好多贴,料到很多大小猿也遇到了这个问题。

看了几篇也没发现有什么好的解决方案。不过有一个网友提到了注册表,让我醍醐灌顶。

首先,启动不了时我第一选择是删除再解压原来的安装包,然并卵;
然后,更换安装根目录(原先在D盘,剪切至E盘),然并卵。
最后,愤然打开"WIN+R",输入“regedit”,进入注册表窗口,接着就兴高采烈的搜索“HBuilder”删除相应注册表条目,直至搜索不出来。

删完注册表,去茶水间倒杯咖啡,闻了一下,回到座位上打开HB的安装目录尝试再次启动。

OK,输入帐号密码,登录成功!!

不废话了,有这种情况的朋友赶紧跑注册表里倒腾去吧!

以上是我个人遇到的情况与解决方法,采纳前请慎重考虑。


建议工程根目录不要放在HB的安装目录,HB丢了不要紧再装一个,但你的工程丢了如果没有备份就该喊娘了!

个人网站:http://www.ipic.so

收起阅读 »

H5游戏改造流应用指南

游戏

传统的H5游戏,只能在浏览器里发行,不能在应用市场发行,也无法自动在桌面留有图标。
这样的H5游戏,体验不足,留存上不去。

流应用不是在浏览器里发行,而是在应用市场发行,在桌面天然有图标,但却也拥有即点即开的特性。
并且运行在流应用里,可以调用操作系统底层的40w api,可实现强大的功能。

下图为在360手机助手搜索传奇世界,可看到流应用的秒开按钮。

流应用为H5游戏提供了什么?

  1. 更高效的发行平台和留存率提升
    通过DCloud与应用市场的合作,流应用可发行到应用市场里,并基于DCloud的流式发行技术实现秒开,过去App下载、安装、启动这3步被合为一步。
    并且自动在桌面留存图标,不像浏览器那样是需要用户操作后才能创建到桌面上。这切实提高了留存率。
  2. 联合登陆-提升注册转化率
    通过流应用提供的联合登陆机制,可直接完成注册,避免用户注册账户的麻烦,白名单合作厂商还可以直接拿到手机号。
    这个机制可以切实提高注册转化率。
    以传奇世界H5的运行数据为例,流应用版的角色创建率比各版平均值提升75%。
  3. 原生支付控件-提升支付成功率
    在流应用平台里可以直接调起支付宝原生支付控件,如果开发商有微信wap支付权限,也可以直接在流应用里使用。
    通过更优秀的体验,可以提高支付成功率。
    以传奇世界H5的运行数据为例,流应用版的付费率比各版平均值提升100%,付费成功率提升50%。
  4. 社交分享-提升二次传播率
    流应用提供的社交分享能力,可以调起原生的微信、微博、qq、短信、邮件等各种社交分享通道,方便的邀请好友和传播。
    分享出去的链接别人点击后,如果手机上有流应用引擎,则会直接秒装好该游戏的流应用并进入特定界面,如果对方手机上没有流应用引擎则出现标准HTML5版本。
    注:流应用引擎的装机覆盖量过亿,目前测试数据是每3个Android设备就有一个能命中。
    通过流应用的分享机制,可以切实提高二次传播率。
  5. 更多操作系统的原生API
    事实上除了上面常用的增强API,流应用提供了原生操作系统40万API的调用能力,完全可以在流应用里随意调用原生API。
    开发者可以充分发挥想象力,摇一摇、扫一扫、原生定位、读取imei、back按键控制、软键盘控制、横竖屏控制、原生音频播放、前后台切换事件...
    流应用没有提供什么?
    流应用没有提供canvas加速器,所以裸奔体验也不错的游戏上流应用比较合适。

综上,可以看出流应用除了提供40万原生api外,在游戏的发行、留存、注册转换、支付、二次传播等方面均进行了强化处理,提升游戏的关键运营数据表现,并且在传奇世界H5的运行中用数据证明了提升效果。

那么如果你拥有一个裸奔体验不错的H5游戏,如何改造成流应用?
基本原则是你需要新建一个流应用微端项目,把微端项目提交到流应用平台,在微端项目里打开在线的H5 URL。

  1. 在http://DCloud.io下载HBuilder工具。这个工具是通用HTML5编辑器,App和web都可以开发。
  2. 在HBuilder里面新建一个移动App项目,打开里面的manifest.json,配好游戏的名称、ico、splash封面图片、splash手动关闭、全屏、设置硬件加速强制打开,参考http://ask.dcloud.net.cn/article/94
  3. 在index.html里跳转到目前的H5的网络URL。
  4. 点菜单发行-发行流应用,根据提示操作。
  5. 然后把H5游戏的现有项目也拖到HBuilder里,成为一个普通的web项目。
  6. 在web项目里写js,调用流应用提供的增强api。
    实现联合登陆plus.oauth、支付plus.payment、分享plus.share等功能。参考http://www.html5plus.org/doc/h5p.html。还可以在HBuilder里新建移动App时选Hello H5+模板,然后点菜单运行-真机运行这个项目来看各种api的调用示例。
    还需要监听back按键,最好是游戏里界面的返回响应plus.key里的back按键,如果没精力全部做,至少游戏退出时需要监听back,一般是监听双击,按一下back时提示一个toast:再按一次退出,然后按第二次back时退出。
  7. 根据流应用的UA来让这些js生效,流应用的ua里包含“StreamApp”字符串,如果要打包为apk或ipa发行,则ua包含"Html5Plus"字符串。其实不管是流应用发行还是原生包发行,只要使用DCloud的客户端引擎ua里就会有"Html5Plus"字符串,同时在流应用模型是ua多增加了“StreamApp”字符串。
  8. 特别要注意一点,大多数H5游戏都有一个网络加载的首屏,即先从服务器取一个首屏等待界面,然后后台继续载资源直到游戏可以进入。
    但在流应用里,这个模式不对。
    流应用splash封面图是本地化的,已经配在了manifest里,此时服务器不需要再请求一个等待界面,多浪费用户流量和增加等待时间。
    也就是从桌面点图标时,流应用与原生app一样是先启动本地splash封面图,然后等待游戏进入,游戏进入后再调用plus.navigator.closeSplashscreen()关闭splash图片即可。
  9. 还可以在你的H5游戏里内嵌一个gostream.js,在非流应用的环境下引入,这个js可以检测手机上是否有流应用引擎,如果有则可以秒开流应用,实现wap流量转换为app流量。参考http://ask.dcloud.net.cn/article/579

以上工作中,涉及增强api调用的工作并不是强制的,不调用也可以申请上线,就是一个普通的H5页游。
但这些增强api不调用,将影响数据转换。

流应用QQ交流群,请加:471285299。

继续阅读 »

传统的H5游戏,只能在浏览器里发行,不能在应用市场发行,也无法自动在桌面留有图标。
这样的H5游戏,体验不足,留存上不去。

流应用不是在浏览器里发行,而是在应用市场发行,在桌面天然有图标,但却也拥有即点即开的特性。
并且运行在流应用里,可以调用操作系统底层的40w api,可实现强大的功能。

下图为在360手机助手搜索传奇世界,可看到流应用的秒开按钮。

流应用为H5游戏提供了什么?

  1. 更高效的发行平台和留存率提升
    通过DCloud与应用市场的合作,流应用可发行到应用市场里,并基于DCloud的流式发行技术实现秒开,过去App下载、安装、启动这3步被合为一步。
    并且自动在桌面留存图标,不像浏览器那样是需要用户操作后才能创建到桌面上。这切实提高了留存率。
  2. 联合登陆-提升注册转化率
    通过流应用提供的联合登陆机制,可直接完成注册,避免用户注册账户的麻烦,白名单合作厂商还可以直接拿到手机号。
    这个机制可以切实提高注册转化率。
    以传奇世界H5的运行数据为例,流应用版的角色创建率比各版平均值提升75%。
  3. 原生支付控件-提升支付成功率
    在流应用平台里可以直接调起支付宝原生支付控件,如果开发商有微信wap支付权限,也可以直接在流应用里使用。
    通过更优秀的体验,可以提高支付成功率。
    以传奇世界H5的运行数据为例,流应用版的付费率比各版平均值提升100%,付费成功率提升50%。
  4. 社交分享-提升二次传播率
    流应用提供的社交分享能力,可以调起原生的微信、微博、qq、短信、邮件等各种社交分享通道,方便的邀请好友和传播。
    分享出去的链接别人点击后,如果手机上有流应用引擎,则会直接秒装好该游戏的流应用并进入特定界面,如果对方手机上没有流应用引擎则出现标准HTML5版本。
    注:流应用引擎的装机覆盖量过亿,目前测试数据是每3个Android设备就有一个能命中。
    通过流应用的分享机制,可以切实提高二次传播率。
  5. 更多操作系统的原生API
    事实上除了上面常用的增强API,流应用提供了原生操作系统40万API的调用能力,完全可以在流应用里随意调用原生API。
    开发者可以充分发挥想象力,摇一摇、扫一扫、原生定位、读取imei、back按键控制、软键盘控制、横竖屏控制、原生音频播放、前后台切换事件...
    流应用没有提供什么?
    流应用没有提供canvas加速器,所以裸奔体验也不错的游戏上流应用比较合适。

综上,可以看出流应用除了提供40万原生api外,在游戏的发行、留存、注册转换、支付、二次传播等方面均进行了强化处理,提升游戏的关键运营数据表现,并且在传奇世界H5的运行中用数据证明了提升效果。

那么如果你拥有一个裸奔体验不错的H5游戏,如何改造成流应用?
基本原则是你需要新建一个流应用微端项目,把微端项目提交到流应用平台,在微端项目里打开在线的H5 URL。

  1. 在http://DCloud.io下载HBuilder工具。这个工具是通用HTML5编辑器,App和web都可以开发。
  2. 在HBuilder里面新建一个移动App项目,打开里面的manifest.json,配好游戏的名称、ico、splash封面图片、splash手动关闭、全屏、设置硬件加速强制打开,参考http://ask.dcloud.net.cn/article/94
  3. 在index.html里跳转到目前的H5的网络URL。
  4. 点菜单发行-发行流应用,根据提示操作。
  5. 然后把H5游戏的现有项目也拖到HBuilder里,成为一个普通的web项目。
  6. 在web项目里写js,调用流应用提供的增强api。
    实现联合登陆plus.oauth、支付plus.payment、分享plus.share等功能。参考http://www.html5plus.org/doc/h5p.html。还可以在HBuilder里新建移动App时选Hello H5+模板,然后点菜单运行-真机运行这个项目来看各种api的调用示例。
    还需要监听back按键,最好是游戏里界面的返回响应plus.key里的back按键,如果没精力全部做,至少游戏退出时需要监听back,一般是监听双击,按一下back时提示一个toast:再按一次退出,然后按第二次back时退出。
  7. 根据流应用的UA来让这些js生效,流应用的ua里包含“StreamApp”字符串,如果要打包为apk或ipa发行,则ua包含"Html5Plus"字符串。其实不管是流应用发行还是原生包发行,只要使用DCloud的客户端引擎ua里就会有"Html5Plus"字符串,同时在流应用模型是ua多增加了“StreamApp”字符串。
  8. 特别要注意一点,大多数H5游戏都有一个网络加载的首屏,即先从服务器取一个首屏等待界面,然后后台继续载资源直到游戏可以进入。
    但在流应用里,这个模式不对。
    流应用splash封面图是本地化的,已经配在了manifest里,此时服务器不需要再请求一个等待界面,多浪费用户流量和增加等待时间。
    也就是从桌面点图标时,流应用与原生app一样是先启动本地splash封面图,然后等待游戏进入,游戏进入后再调用plus.navigator.closeSplashscreen()关闭splash图片即可。
  9. 还可以在你的H5游戏里内嵌一个gostream.js,在非流应用的环境下引入,这个js可以检测手机上是否有流应用引擎,如果有则可以秒开流应用,实现wap流量转换为app流量。参考http://ask.dcloud.net.cn/article/579

以上工作中,涉及增强api调用的工作并不是强制的,不调用也可以申请上线,就是一个普通的H5页游。
但这些增强api不调用,将影响数据转换。

流应用QQ交流群,请加:471285299。

收起阅读 »

在哪里学习跨平台app开发、HBuilder、MUI的课程?

视频教程 学习 外包 mui HBuilder

在今年这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识, 懂一些CSS和JavaScript就够了,跨平台移动APP开发是利用HTML5+CSS3+JS,快速开发出本地App,一次开发,多平台适配,效果与原生App相媲美。学习跨平台app开发就在这里>>>跨平台app开发全套课程

Dcloud官方合作培训机构-国内首推跨平台app开发培训-东翌学院 咨询课程老师QQ410355878,小班直播教学+课后辅导+全套课程视频+源码,从零基础到实战,30天学会跨平台App开发!

继续阅读 »

在今年这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识, 懂一些CSS和JavaScript就够了,跨平台移动APP开发是利用HTML5+CSS3+JS,快速开发出本地App,一次开发,多平台适配,效果与原生App相媲美。学习跨平台app开发就在这里>>>跨平台app开发全套课程

Dcloud官方合作培训机构-国内首推跨平台app开发培训-东翌学院 咨询课程老师QQ410355878,小班直播教学+课后辅导+全套课程视频+源码,从零基础到实战,30天学会跨平台App开发!

收起阅读 »

我用Hbuilder打包html,写cookie不成功。我的html就下文一个html文件。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf-8">
mui.init();
</script>
<script>
function getdizhi()
{
var micomosid = document.getElementById("mosip").value;
var exp = new Date();
exp.setTime(exp.getTime() 30 24 60 60 1000);
document.cookie = "mico_cook=" micomosid ";expires=" exp.toGMTString() ";path=/";
window.location.href="http://" micomosid ":81/index.asp";
}

window.onload=function()
{
if (readcookie("mico_cook"))
{
document.getElementById("mosip").value = readcookie("mico_cook");
}
}

var mycookie = document.cookie;
function readcookie(name)
{
var start1 = mycookie.indexOf(name "=");
if (start1== -1)
alert("请输入服务器IP1");
else
{
start=mycookie.indexOf("=",start1) 1;
var end = mycookie.indexOf(";",start);
if (end==-1)
{
end=mycookie.length;}
var value=unescape(mycookie.substring(start,end));
if (value==null)
{alert("请输入服务器IP2");}
else
{return value;}
}
}
</script>
</head>
<body>
<table width="100%">
<tr height="40">
<td align="center"> </td>
</tr>
<tr height="40">
<td align="center"><img src="logo.png" border="0" width="32" height="32"></td>
</tr>
<tr height="40">
<td align="center"><font color="#666666">服务器LAN IP:</font></td>
</tr>
<tr height="40">
<td align="center"><input name="mosip" id="mosip" type="text" value="" style= "width:160px; height:32px; font-size:20px; color:#666666" /></td>
</tr>
<tr height="40">
<td align="center"><input type="button" value="进 入" onClick="getdizhi()" style= "width:160px; height:32px;" /></td>
</tr>
<tr height="40">
<td align="center"><font color="#666666"> </td>
</tr>
<tr height="40">
<td align="center"><font color="#666666">版权所有</td>
</tr>
</table>
</body>
</html>

继续阅读 »

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf-8">
mui.init();
</script>
<script>
function getdizhi()
{
var micomosid = document.getElementById("mosip").value;
var exp = new Date();
exp.setTime(exp.getTime() 30 24 60 60 1000);
document.cookie = "mico_cook=" micomosid ";expires=" exp.toGMTString() ";path=/";
window.location.href="http://" micomosid ":81/index.asp";
}

window.onload=function()
{
if (readcookie("mico_cook"))
{
document.getElementById("mosip").value = readcookie("mico_cook");
}
}

var mycookie = document.cookie;
function readcookie(name)
{
var start1 = mycookie.indexOf(name "=");
if (start1== -1)
alert("请输入服务器IP1");
else
{
start=mycookie.indexOf("=",start1) 1;
var end = mycookie.indexOf(";",start);
if (end==-1)
{
end=mycookie.length;}
var value=unescape(mycookie.substring(start,end));
if (value==null)
{alert("请输入服务器IP2");}
else
{return value;}
}
}
</script>
</head>
<body>
<table width="100%">
<tr height="40">
<td align="center"> </td>
</tr>
<tr height="40">
<td align="center"><img src="logo.png" border="0" width="32" height="32"></td>
</tr>
<tr height="40">
<td align="center"><font color="#666666">服务器LAN IP:</font></td>
</tr>
<tr height="40">
<td align="center"><input name="mosip" id="mosip" type="text" value="" style= "width:160px; height:32px; font-size:20px; color:#666666" /></td>
</tr>
<tr height="40">
<td align="center"><input type="button" value="进 入" onClick="getdizhi()" style= "width:160px; height:32px;" /></td>
</tr>
<tr height="40">
<td align="center"><font color="#666666"> </td>
</tr>
<tr height="40">
<td align="center"><font color="#666666">版权所有</td>
</tr>
</table>
</body>
</html>

收起阅读 »

Hbuilder 折叠代码问题

HBuilder HTML5 技巧

各位大神我是> 小白 你们现在讨论的都感觉好高大上 我劳烦你们看下我的问题 我就想请教一个 Hbuilder在编写html5的时候左边有个折叠代码的功能,用基本上一个标签一个折叠按钮,但是当我下载了php插件之后就不能折叠代码,只有html5的头文件那里有一个折叠的按钮其他的标签都没有是什么问题
因为代码敲击的多了,想转回去改一些css 都得重新去找,如果没有折叠标签会很浪费时间!!!

继续阅读 »

各位大神我是> 小白 你们现在讨论的都感觉好高大上 我劳烦你们看下我的问题 我就想请教一个 Hbuilder在编写html5的时候左边有个折叠代码的功能,用基本上一个标签一个折叠按钮,但是当我下载了php插件之后就不能折叠代码,只有html5的头文件那里有一个折叠的按钮其他的标签都没有是什么问题
因为代码敲击的多了,想转回去改一些css 都得重新去找,如果没有折叠标签会很浪费时间!!!

收起阅读 »

【分享】JS 日期工具类-基于yDate

日期 技术分享 HTML5

前言:最近在用到JS日期操作时,发现有一些不方便,于是搜素了一些网上的资料,基于一个开源工具类-yDate 进行了个性化定制,封装成了一个日期工具类
工具函数大概介绍:
1.普通的日期操作

  1. 获得一些绝对时间,如1970年 到现在的绝对年,月份,日期,描述,毫秒数等等
  2. 日期比较,克隆,开始时间,结束时间,字符串(输出时可以自定义格式)输出等
  3. 日期相加,相减(返回一个新的日期对象), 比如1月31日 1天会自动变为 2月1日等等
  4. 简化构造,可以传入字符串进行构造等等
  5. 更多请看源码
    说明-基于yDate:| yDate.js | Copyright (c) 2013 yao.yl | email: redrainyi@126.com | Date: 2012-09-03 | *
    原地址: http://www.oschina.net/code/snippet_913265_20123

源码如下:

/**  
 * @description 日期工具类  
 * 原作来源: | yDate.js | Copyright (c) 2013 yao.yl | email: redrainyi@126.com | Date: 2012-09-03 | *   
 * 地址: http://www.oschina.net/code/snippet_913265_20123#comments  
 * 改动说明: 针对yDate进行了一些个性化的修改,以及增加了一些工具函数  
 * @author dailc  dailc  
 * @version 2.0  
 * @time 2016-01-14 12:57:57  
 * 功能模块:  
 * Date相关模块********************************  
 * core/MobileFrame/DateUtil  
 * 1.构造方法  
 * 2.对象的相关功能函数-见源码和文档  
 * Date相关模块结束*****************************  
 */  
(function(exports) {  
    "use strict";  
    var objectPrototypeToString = Object.prototype.toString;  
    /**  
     * 日期匹配的正则表达式  
     * Y:年  
     * M:月  
     * D:日  
     * h:小时  
     * m:分钟  
     * s:秒  
     * i:毫秒  
     * w:星期(小写的)  
     * W:星期(大写的)  
     */  
    var SIGN_DATE_REG = /([YMDhmsiWw])(\1*)/g;  
    /**  
     * 默认的pattern  
     * 'YYYY-MM-DD hh:mm:ss:iii'  
     */  
    var DEFAULT_PATTERN = 'YYYY-MM-DD hh:mm:ss:iii';  
    /**  
     * @description 判断一个值是否是日期类型  
     * @param {Object} value  
     */  
    function isDate(value) {  
        return objectPrototypeToString.call(value) === '[object Date]';  
    };  
    /**  
     * @description 复制一个日期,如果传入的不是日期,会返回一个最新的日期  
     * @param {Date} targetDate  
     */  
    function cloneDate(targetDate, callBack) {  
        //绝对时间,从1970.1.1开始的毫秒数  
        var absoluteTime = (isDate(targetDate)) ? targetDate.getTime() : undefined;  
        var mDate = new Date(absoluteTime);  
        var year = mDate.getFullYear(), //  
            month = mDate.getMonth(), //  
            date = mDate.getDate(), //  
            hours = mDate.getHours(), //  
            minutes = mDate.getMinutes(), //   
            seconds = mDate.getSeconds(); //  
        //!! 代表将后面的转为一个布尔表达式   例如 !!a 就相当于 a||false  
        (!!callBack) && callBack(mDate, year, month, date, hours, minutes, seconds);  
        return mDate;  
    };  
    /**  
     * @description 日期解析,将日期字符串根据特定的匹配字符串解析为日期格式  
     * 解析失败会返回null,如果传入了奇怪的匹配字符串,会产生奇怪的时间  
     * @param {String} dateString 日期字符串  
     * @param {String} pattern 匹配字符串,可以手动传入,或者采取默认  
     * 手动传入需要和日期字符串保持一致  
     */  
    function parseDate(dateString, pattern) {  

        try {  
            //() 是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。  
            //(\s*)表示连续空格的字符串。  
            //[]是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。  
            //[\s*]表示空格或者*号。  
            //{}一般用来表示匹配的长度,比如 \s{3} 表示匹配三个空格,\s[1,3]表示匹配一到三个空格。  
            //(\1)是后向引用,代表后面引用前面第一个()中的内容  
            //根据日期格式来匹配  
            var matchs1 = (pattern || (dateString.length === 10 ? 'YYYY-MM-DD' : (dateString.length === 19 ? 'YYYY-MM-DD hh:mm:ss' : 'YYYY-MM-DD hh:mm:ss:iii'))).match(SIGN_DATE_REG);  
            //根据整数来匹配,将实际的时间数据提取出来  
            var matchs2 = dateString.match(/(\d)+/g);  
            if (matchs1.length > 0) {  
                //第一个匹配字符串需要大于0才行  
                //生成一个最原始的时间-1970-01-01年的  
                var mDate = new Date(1970, 0, 1);  
                //遍历,分别设置年月日,分秒等等  
                for (var i = 0; i < matchs1.length; i++) {  
                    //这个分别是  年,月,日  时,分,秒等等  
                    var mTarget = parseInt(matchs2[i], 10);  
                    switch (matchs1[i].charAt(0) || '') {  
                        //这个matchs1[i]有可能是  YYYY  所以只去第一个字符  
                        case 'Y':  
                            mDate.setFullYear(mTarget);  
                            break;  
                        case 'M':  
                            mDate.setMonth(mTarget - 1);  
                            break;  
                        case 'D':  
                            mDate.setDate(mTarget);  
                            break;  
                        case 'h':  
                            mDate.setHours(mTarget);  
                            break;  
                        case 'm':  
                            mDate.setMinutes(mTarget);  
                            break;  
                        case 's':  
                            mDate.setSeconds(mTarget);  
                            break;  
                        case 'i':  
                            mDate.setMilliseconds(mTarget);  
                            break;  
                        default:  
                            //默认不操作  
                    }  
                }  
                return mDate;  
            }  
        } catch (e) {  

        }  
        return null;  
    };  
    /**  
     * @description 将字符串多余的长度补齐0  
     * @param {String} s  
     * @param {Number} len  
     */  
    function paddingFillWith0(s, len) {  
        var len = len - (s + "").length;  
        for (var i = 0; i < len; i++) {  
            s = "0" + s;  
        }  
        return s;  
    }  
    /**  
     * @description 格式化时间,返回格式化后的字符串  
     * 如果格式不合要求,返回null  
     * @param {Date} value 目标时间  
     * @param {String} pattern 匹配字符串  
     */  
    function formatDateToString(value, pattern) {  
        if (!isDate(value)) {  
            return '';  
        }  
        try {  
            //默认为输出所有的  
            pattern = pattern || DEFAULT_PATTERN;  
            return pattern.replace(SIGN_DATE_REG, function($0) {  
                //如果传入一个yyyy-MM-dd 的表达式  
                //实际上这个函数会分别回调多次 没符合一次匹配就回调一次  
                //$0:yyyy  $0:MM $0:dd  依次类推  
                //console.log('$0:'+$0);  
                switch ($0.charAt(0)) {  
                    case 'Y':  
                        return paddingFillWith0(value.getFullYear(), $0.length);  
                    case 'M':  
                        return paddingFillWith0(value.getMonth() + 1, $0.length);  
                    case 'D':  
                        return paddingFillWith0(value.getDate(), $0.length);  
                    case 'h':  
                        return paddingFillWith0(value.getHours(), $0.length);  
                    case 'm':  
                        return paddingFillWith0(value.getMinutes(), $0.length);  
                    case 's':  
                        return paddingFillWith0(value.getSeconds(), $0.length);  
                    case 'i':  
                        return paddingFillWith0(value.getMilliseconds(), $0.length);  
                    case 'w':  
                        return value.getDay();  
                    case 'W':  
                        //自动将星期转为了大写  
                        var week = ['日', '一', '二', '三', '四', '五', '六'];  
                        return paddingFillWith0(week[value.getDay()], $0.length);  
                    default:  
                        return '';  
                }  
            });  
        } catch (e) {  
            console.log('error:' + e);  
            return '';  
        }  
    };  
    /**  
     * @description 得到实际日期最大值  
     * @param {Date} date  
     */  
    function getActualMaximum(date) {  
        var vDate = new Date(date.getTime());  
        vDate.setMonth(vDate.getMonth() + 1);  
        vDate.setDate(0);  
        return vDate.getDate();  
    }  
    /**  
     * @description 定义一个自定义日期类的构造方法,  
     * 里面封装日期的常用操作,不通过自带的日期来操作  
     * @constructor 这是一个构造方法  
     */  
    function MyDate() {  
        var p0 = arguments[0];  
        var p1 = arguments[1];  
        //isFinite 用于判断是否是无穷大  
        //如果 number 是有限数字(或可转换为有限数字),那么返回 true  
        //如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false  
        if (typeof p0 === 'number' && isFinite(value)) {  
            this.myDate = new Date(p0); //millis  
        } else if (isDate(p0)) {  
            this.myDate = new Date(p0.getTime());  
        } else if (typeof p0 === 'string') {  
            if (typeof p1 !== 'string' && typeof p1 !== 'undefined') {  
                p1 = undefined;  
            }  
            this.myDate = parseDate(p0, p1);  
        } else if (arguments.length == 0) {  
            this.myDate = new Date();  
        } else {  
            throw 'MyDate Constructor Error!';  
        }  
    };  
    /**  
     * @description 给一个日期设置年份  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setYearG(finalYear, mDate, self) {  
        mDate.setFullYear(finalYear);  
    }  
    /**  
     * @description 给一个日期设置月份  
     * 之所以要单独将设置月份(年,日,时...)的函数抽取出来,是因为  
     * 在日期时间 加,减操作时,会涉及到一个进位问题: 比如,1月31日的下一天应该是2月1日...  
     * 所以单独封装成函数便于调用  
     * 之所以没有 直接调用plusMonth,plusYear...  
     * 是因为这个操作中间有回调,多个回调嵌套后,无法同步返回最准确的数据  
     * (可以自行测试)  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setMonthG(finalMon, mDate, self) {  
        //month 为 0-11  
        if (finalMon > 11) {  
            finalMon = finalMon - 12;  
            setYearG(mDate.getFullYear() + 1, mDate, self);  
        } else if (finalMon < 0) {  
            finalMon += 12;  
            setYearG(mDate.getFullYear() - 1, mDate, self);  
        }  
        /*  
         * 关于月份顺延的bug  
         发现如下规律:只要setMonth()的参数为小于31天的月份时就会变为下一个月。  
          原因是:因为当前月份是31天,而设置的月份小于31天,就会把日期顺延。在setMonth的说明是这样的:  
          dateObj.setMonth(numMonth[, dateVal])  
          dateVal  
        可选项。一个代表日期的数值。  
        如果没有提供此参数,那么将使用通过调用 getDate 方法而得到的数值。  
        所以,从对dataVal参数的说明可以看出,在设置月份的同时,  
        使用getDate获取日期,并使用得到的日期值设置了日期。  
        于是就会发生月份顺延的情况。  
        解决方法:  
      1、设置月份时,将日期设为1,记setMonth(month, 1),  
      当然可以在setMonth之前先调用setDate()设置日期;  
      2、也可以在初始化Date对象时,就指定一个日期,也就是使用:  
      dateObj = new Date(year, month, date[, hours[, minutes[, seconds[,ms]]]]) 的形式。  
      3、也可以使用setFullYear()同时设置年、月、日,即setFullYear(numYear[, numMonth[, numDate]])。   
        *bug简单说明:  
        * 如果当前是10月31日,然后设置月份为11,由于11月没有31天,所以月份会顺延  
        * 自动变为12月,所以解决方法是要在设置月份前先把日期设置下,然后之后再继续设置日期  
        * (因为日期肯定是需要改变的)  
        *   
        * * * */  
        mDate.setMonth(finalMon, 1);  

    }  
    /**  
     * @description 给一个日期设置日期  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setDateG(finalDay, mDate, self) {  
        var month = mDate.getMonth();  
        var monthDays = self.getMonthDays(month + 1);  
        if (finalDay > monthDays) {  
            finalDay -= monthDays;  
            setMonthG(mDate.getMonth() + 1, mDate, self);  
        } else if (finalDay <= 0) {  
            var lastMonthDay = month > 0 ? self.getMonthDays((month + 1 - 1)) : self.getMonthDays(12);  
            finalDay += lastMonthDay;  
            setMonthG(mDate.getMonth() - 1, mDate, self);  
        }  
        mDate.setDate(finalDay);  
    }  
    /**  
     * @description 给一个日期设置小时  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setHourG(finalHour, mDate, self) {  
        if (finalHour >= 24) {  
            finalHour -= 24;  
            setDateG(mDate.getDate() + 1, mDate, self);  
        } else if (finalHour < 0) {  
            finalHour += 24;  
            setDateG(mDate.getDate() - 1, mDate, self);  
        }  
        mDate.setHours(finalHour);  
    }  
    /**  
     * @description 给一个日期设置分钟  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setMinG(finalMin, mDate, self) {  
        if (finalMin >= 60) {  
            finalMin -= 60;  
            setHourG(mDate.getHours() + 1, mDate, self);  
        } else if (finalHour < 0) {  
            finalMin += 60;  
            setHourG(mDate.getHours() - 1, mDate, self);  
        }  
        mDate.setMinutes(finalMin);  
    }  
    /**  
     * @description 给一个日期设置秒  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setSecG(finalSec, mDate, self) {  
        if (finalSec >= 60) {  
            finalSec -= 60;  
            setMinG(mDate.getMinutes() + 1, mDate, self);  
        } else if (finalSec < 0) {  
            finalSec += 60;  
            setMinG(mDate.getMinutes() - 1, mDate, self);  
        }  
        mDate.setSeconds(finalSec);  
    }  
    /**  
     * @description 通过扩充原型添加方法  
     */  
    MyDate.prototype = {  
        /**  
         * @description 得到一个月有多少天  
         * @param {Number} month 对应的月份  
         */  
        getMonthDays: function(month) {  
            switch (month) {  
                case 1:  
                case 3:  
                case 5:  
                case 7:  
                case 8:  
                case 10:  
                case 12:  
                    return 31;  
                    break;  
                case 4:  
                case 6:  
                case 9:  
                case 11:  
                    return 30;  
                    break;  
                case 2:  
                    if (this.isLeapYear()) {  
                        return 29;  
                    } else {  
                        return 28;  
                    }  
                    break;  
                default:  
                    return 0;  
                    break;  
            }  
        },  
        /**  
         * @description 年份相加,返回一个新的日期  
         * @param {Object} value  
         */  
        plusYear: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                setYearG(year + value, mDate, self);  
            }));  
        },  
        plusMonth: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                setMonthG(month + value, mDate, self);  
            }));  
        },  
        plusDate: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalDay = date + value;  
                setDateG(finalDay, mDate, self);  
            }));  
        },  
        plusHours: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalHour = hours + value;  
                setHourG(finalHour, mDate, self);  
            }));  
        },  
        plusMinutes: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalMin = minutes + value;  
                setMinG(finalMin, mDate, self);  
            }));  
        },  
        plusSeconds: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalSec = seconds + value;  
                setSecG(finalSec, mDate, self);  
            }));  
        },  
        minusYear: function(value) {  
            return this.plusYear(-value);  
        },  
        minusMonth: function(value) {  
            return this.plusMonth(-value);  
        },  
        minusDate: function(value) {  
            return this.plusDate(-value);  
        },  
        minusHours: function(value) {  
            return this.plusHours(-value);  
        },  
        minusMinutes: function(value) {  
            return this.plusMinutes(-value);  
        },  
        minusSeconds: function(value) {  
            return this.plusSeconds(-value);  
        },  
        setYear: function(value) {  
            this.myDate.setFullYear(value);  
        },  
        setMonth: function(value) {  
            this.myDate.setMonth(value - 1);  
        },  
        setDate: function(value) {  
            this.myDate.setDate(value);  
        },  
        setHours: function(value) {  
            this.myDate.setHours(value);  
        },  
        setMinutes: function(value) {  
            this.myDate.setMinutes(value);  
        },  
        setSeconds: function(value) {  
            this.myDate.setSeconds(value);  
        },  
        setMilliseconds: function(value) {  
            this.myDate.setMilliseconds(value);  
        },  
        getYear: function() {  
            return this.myDate.getFullYear();  
        },  
        getMonth: function() {  
            //比普通月份小1  
            return this.myDate.getMonth();  
        },  
        getDate: function() {  
            return this.myDate.getDate();  
        },  
        getHours: function() {  
            return this.myDate.getHours();  
        },  
        getMinutes: function() {  
            return this.myDate.getMinutes();  
        },  
        getSeconds: function() {  
            return this.myDate.getSeconds();  
        },  
        getMilliseconds: function() {  
            return this.myDate.getMilliseconds();  
        },  
        /**  
         * @description 得到从1970至今多少年  
         */  
        getAbsoluteYear: function() {  
            return this.myDate.getFullYear() - 1970;  
        },  
        getAbsoluteMonth: function() {  
            return this.getAbsoluteYear() * 12 + this.myDate.getMonth();  
        },  
        /**  
         * @description 获得绝对日期  
         * 这里采取的方法为 得到从1970至今的毫秒数,然后转为天  
         */  
        getAbsoluteDate: function() {  
            var absoluteMillons = this.getAbsoluteMillonsTime();  
            //毫秒-秒-分-时-天  
            return parseInt(absoluteMillons / 1000 / 60 / 60 / 24, 10);  
        },  
        getAbsoluteHours: function() {  
            return this.getAbsoluteDate() * 24 + this.myDate.getHours();  
        },  
        getAbsoluteMinutes: function() {  
            return this.getAbsoluteHours() * 60 + this.myDate.getMinutes();  
        },  
        getAbsoluteSeconds: function() {  
            return this.getAbsoluteMinutes() * 60 + this.myDate.getSeconds();  
        },  
        /**  
         * @description 得到从1970年开始到现在的毫秒数  
         * 单位是毫秒  
         */  
        getAbsoluteMillonsTime: function() {  
            return this.myDate.getTime();  
        },  
        getDayOfWeek: function(pattern) {  
            //0(周日) 到 6(周六  
            //var week = ['日','一','二','三','四','五','六'];  
            return this.myDate.getDay();  
        },  
        isLeapYear: function() {  
            return (0 == this.myDate.getYear() % 4 && ((this.myDate.getYear() % 100 != 0) || (this.myDate.getYear() % 400 == 0)));  
        },  
        toDate: function() {  
            return cloneDate(this.myDate);  
        },  
        clone: function() {  
            return new MyDate(cloneDate(this.myDate));  
        },  
        /**  
         * @description 得到一个日期的最小时间  
         * @param {String}method = [YYYY|MM|DD|hh|mm|ss] field 分别代表年,月,日,时,分,秒的抉择  
         */  
        getBegin: function(field) {  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                switch (field) {  
                    case 'YYYY': //year  
                        mDate.setMonth(0);  
                        mDate.setDate(1);  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'MM': //month  
                        mDate.setDate(1);  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                    case 'DD': //date  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'hh': //hour  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'mm': //minute  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'ss': //seconds  
                        mDate.setMilliseconds(0);  
                        break;  
                    default:  
                        //Ignore  
                }  
            }));  
        },  
        /**  
         * @description 得到一个日期的最大时间  
         * @param {String}method = [YYYY|MM|DD|hh|mm|ss] field 分别代表年,月,日,时,分,秒的抉择  
         */  
        getEnd: function(field) {  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                switch (field) {  
                    case 'YYYY': //year  
                        mDate.setMonth(11);  
                        mDate.setDate(31);  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'MM': //month  
                        mDate.setDate(getActualMaximum(mDate));  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                    case 'DD': //date  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'hh': //hour  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'mm': //minute  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'ss': //seconds  
                        mDate.setMilliseconds(999);  
                        break;  
                    default:  
                        //Ignore  
                }  
            }));  
        },  
        /**  
         * @description 和另一个日期比较,另一个日期必须为MyDate型  
         * @param {Date} targetDate 目标日期,MyDate型  
         * @param {String} method = [YYYY|MM|DD|hh|mm|ss|iii] pettern 选择字符串,目前支持 yyyy,MM,dd,HH,mm,ss以及iii  
         * 分别代表比较到某一个层次,默认为比较到毫秒  
         * @return {Number} 返回结果  
         * -1:比较字符对象不合法  
         * 0:两个日期相等  
         * 1:本日期大于目标日期  
         * 2:本日期小于目标日期  
         */  
        compare: function(targetDate, pattern) {  
            //如果不是时间类型,而且不是MyDate类型  
            if (!isDate(targetDate) && !(targetDate instanceof MyDate)) {  
                return -1;  
            }  
            //默认为毫秒  
            pattern = pattern || 'iii';  
            if (pattern === 'YYYY') {  
                if (this.getAbsoluteYear() == targetDate.getAbsoluteYear()) {  
                    return 0;  
                } else if (this.getAbsoluteYear() > targetDate.getAbsoluteYear()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'MM') {  
                if (this.getAbsoluteMonth() == targetDate.getAbsoluteMonth()) {  
                    return 0;  
                } else if (this.getAbsoluteMonth() > targetDate.getAbsoluteMonth()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'DD') {  
                if (this.getAbsoluteDate() == targetDate.getAbsoluteDate()) {  
                    return 0;  
                } else if (this.getAbsoluteDate() > targetDate.getAbsoluteDate()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'hh') {  
                if (this.getAbsoluteHours() == targetDate.getAbsoluteHours()) {  
                    return 0;  
                } else if (this.getAbsoluteHours() > targetDate.getAbsoluteHours()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'mm') {  
                if (this.getAbsoluteMinutes() == targetDate.getAbsoluteMinutes()) {  
                    return 0;  
                } else if (this.getAbsoluteMinutes() > targetDate.getAbsoluteMinutes()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'ss') {  
                if (this.getAbsoluteSeconds() == targetDate.getAbsoluteSeconds()) {  
                    return 0;  
                } else if (this.getAbsoluteSeconds() > targetDate.getAbsoluteSeconds()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else {  
                if (this.getAbsoluteMillonsTime() == targetDate.getAbsoluteMillonsTime()) {  
                    return 0;  
                } else if (this.getAbsoluteMillonsTime() > targetDate.getAbsoluteMillonsTime()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            }  
        },  
        isMoreThan: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 1 ? true : false;  
        },  
        isLessThan: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 2 ? true : false;  
        },  
        isEqual: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 0 ? true : false;  
        },  
        toString: function(pattern) {  
            return formatDateToString(this.myDate, pattern);  
        }  
    };  
    exports.MyDate = MyDate;       
})(window.DateUtil={});
继续阅读 »

前言:最近在用到JS日期操作时,发现有一些不方便,于是搜素了一些网上的资料,基于一个开源工具类-yDate 进行了个性化定制,封装成了一个日期工具类
工具函数大概介绍:
1.普通的日期操作

  1. 获得一些绝对时间,如1970年 到现在的绝对年,月份,日期,描述,毫秒数等等
  2. 日期比较,克隆,开始时间,结束时间,字符串(输出时可以自定义格式)输出等
  3. 日期相加,相减(返回一个新的日期对象), 比如1月31日 1天会自动变为 2月1日等等
  4. 简化构造,可以传入字符串进行构造等等
  5. 更多请看源码
    说明-基于yDate:| yDate.js | Copyright (c) 2013 yao.yl | email: redrainyi@126.com | Date: 2012-09-03 | *
    原地址: http://www.oschina.net/code/snippet_913265_20123

源码如下:

/**  
 * @description 日期工具类  
 * 原作来源: | yDate.js | Copyright (c) 2013 yao.yl | email: redrainyi@126.com | Date: 2012-09-03 | *   
 * 地址: http://www.oschina.net/code/snippet_913265_20123#comments  
 * 改动说明: 针对yDate进行了一些个性化的修改,以及增加了一些工具函数  
 * @author dailc  dailc  
 * @version 2.0  
 * @time 2016-01-14 12:57:57  
 * 功能模块:  
 * Date相关模块********************************  
 * core/MobileFrame/DateUtil  
 * 1.构造方法  
 * 2.对象的相关功能函数-见源码和文档  
 * Date相关模块结束*****************************  
 */  
(function(exports) {  
    "use strict";  
    var objectPrototypeToString = Object.prototype.toString;  
    /**  
     * 日期匹配的正则表达式  
     * Y:年  
     * M:月  
     * D:日  
     * h:小时  
     * m:分钟  
     * s:秒  
     * i:毫秒  
     * w:星期(小写的)  
     * W:星期(大写的)  
     */  
    var SIGN_DATE_REG = /([YMDhmsiWw])(\1*)/g;  
    /**  
     * 默认的pattern  
     * 'YYYY-MM-DD hh:mm:ss:iii'  
     */  
    var DEFAULT_PATTERN = 'YYYY-MM-DD hh:mm:ss:iii';  
    /**  
     * @description 判断一个值是否是日期类型  
     * @param {Object} value  
     */  
    function isDate(value) {  
        return objectPrototypeToString.call(value) === '[object Date]';  
    };  
    /**  
     * @description 复制一个日期,如果传入的不是日期,会返回一个最新的日期  
     * @param {Date} targetDate  
     */  
    function cloneDate(targetDate, callBack) {  
        //绝对时间,从1970.1.1开始的毫秒数  
        var absoluteTime = (isDate(targetDate)) ? targetDate.getTime() : undefined;  
        var mDate = new Date(absoluteTime);  
        var year = mDate.getFullYear(), //  
            month = mDate.getMonth(), //  
            date = mDate.getDate(), //  
            hours = mDate.getHours(), //  
            minutes = mDate.getMinutes(), //   
            seconds = mDate.getSeconds(); //  
        //!! 代表将后面的转为一个布尔表达式   例如 !!a 就相当于 a||false  
        (!!callBack) && callBack(mDate, year, month, date, hours, minutes, seconds);  
        return mDate;  
    };  
    /**  
     * @description 日期解析,将日期字符串根据特定的匹配字符串解析为日期格式  
     * 解析失败会返回null,如果传入了奇怪的匹配字符串,会产生奇怪的时间  
     * @param {String} dateString 日期字符串  
     * @param {String} pattern 匹配字符串,可以手动传入,或者采取默认  
     * 手动传入需要和日期字符串保持一致  
     */  
    function parseDate(dateString, pattern) {  

        try {  
            //() 是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。  
            //(\s*)表示连续空格的字符串。  
            //[]是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。  
            //[\s*]表示空格或者*号。  
            //{}一般用来表示匹配的长度,比如 \s{3} 表示匹配三个空格,\s[1,3]表示匹配一到三个空格。  
            //(\1)是后向引用,代表后面引用前面第一个()中的内容  
            //根据日期格式来匹配  
            var matchs1 = (pattern || (dateString.length === 10 ? 'YYYY-MM-DD' : (dateString.length === 19 ? 'YYYY-MM-DD hh:mm:ss' : 'YYYY-MM-DD hh:mm:ss:iii'))).match(SIGN_DATE_REG);  
            //根据整数来匹配,将实际的时间数据提取出来  
            var matchs2 = dateString.match(/(\d)+/g);  
            if (matchs1.length > 0) {  
                //第一个匹配字符串需要大于0才行  
                //生成一个最原始的时间-1970-01-01年的  
                var mDate = new Date(1970, 0, 1);  
                //遍历,分别设置年月日,分秒等等  
                for (var i = 0; i < matchs1.length; i++) {  
                    //这个分别是  年,月,日  时,分,秒等等  
                    var mTarget = parseInt(matchs2[i], 10);  
                    switch (matchs1[i].charAt(0) || '') {  
                        //这个matchs1[i]有可能是  YYYY  所以只去第一个字符  
                        case 'Y':  
                            mDate.setFullYear(mTarget);  
                            break;  
                        case 'M':  
                            mDate.setMonth(mTarget - 1);  
                            break;  
                        case 'D':  
                            mDate.setDate(mTarget);  
                            break;  
                        case 'h':  
                            mDate.setHours(mTarget);  
                            break;  
                        case 'm':  
                            mDate.setMinutes(mTarget);  
                            break;  
                        case 's':  
                            mDate.setSeconds(mTarget);  
                            break;  
                        case 'i':  
                            mDate.setMilliseconds(mTarget);  
                            break;  
                        default:  
                            //默认不操作  
                    }  
                }  
                return mDate;  
            }  
        } catch (e) {  

        }  
        return null;  
    };  
    /**  
     * @description 将字符串多余的长度补齐0  
     * @param {String} s  
     * @param {Number} len  
     */  
    function paddingFillWith0(s, len) {  
        var len = len - (s + "").length;  
        for (var i = 0; i < len; i++) {  
            s = "0" + s;  
        }  
        return s;  
    }  
    /**  
     * @description 格式化时间,返回格式化后的字符串  
     * 如果格式不合要求,返回null  
     * @param {Date} value 目标时间  
     * @param {String} pattern 匹配字符串  
     */  
    function formatDateToString(value, pattern) {  
        if (!isDate(value)) {  
            return '';  
        }  
        try {  
            //默认为输出所有的  
            pattern = pattern || DEFAULT_PATTERN;  
            return pattern.replace(SIGN_DATE_REG, function($0) {  
                //如果传入一个yyyy-MM-dd 的表达式  
                //实际上这个函数会分别回调多次 没符合一次匹配就回调一次  
                //$0:yyyy  $0:MM $0:dd  依次类推  
                //console.log('$0:'+$0);  
                switch ($0.charAt(0)) {  
                    case 'Y':  
                        return paddingFillWith0(value.getFullYear(), $0.length);  
                    case 'M':  
                        return paddingFillWith0(value.getMonth() + 1, $0.length);  
                    case 'D':  
                        return paddingFillWith0(value.getDate(), $0.length);  
                    case 'h':  
                        return paddingFillWith0(value.getHours(), $0.length);  
                    case 'm':  
                        return paddingFillWith0(value.getMinutes(), $0.length);  
                    case 's':  
                        return paddingFillWith0(value.getSeconds(), $0.length);  
                    case 'i':  
                        return paddingFillWith0(value.getMilliseconds(), $0.length);  
                    case 'w':  
                        return value.getDay();  
                    case 'W':  
                        //自动将星期转为了大写  
                        var week = ['日', '一', '二', '三', '四', '五', '六'];  
                        return paddingFillWith0(week[value.getDay()], $0.length);  
                    default:  
                        return '';  
                }  
            });  
        } catch (e) {  
            console.log('error:' + e);  
            return '';  
        }  
    };  
    /**  
     * @description 得到实际日期最大值  
     * @param {Date} date  
     */  
    function getActualMaximum(date) {  
        var vDate = new Date(date.getTime());  
        vDate.setMonth(vDate.getMonth() + 1);  
        vDate.setDate(0);  
        return vDate.getDate();  
    }  
    /**  
     * @description 定义一个自定义日期类的构造方法,  
     * 里面封装日期的常用操作,不通过自带的日期来操作  
     * @constructor 这是一个构造方法  
     */  
    function MyDate() {  
        var p0 = arguments[0];  
        var p1 = arguments[1];  
        //isFinite 用于判断是否是无穷大  
        //如果 number 是有限数字(或可转换为有限数字),那么返回 true  
        //如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false  
        if (typeof p0 === 'number' && isFinite(value)) {  
            this.myDate = new Date(p0); //millis  
        } else if (isDate(p0)) {  
            this.myDate = new Date(p0.getTime());  
        } else if (typeof p0 === 'string') {  
            if (typeof p1 !== 'string' && typeof p1 !== 'undefined') {  
                p1 = undefined;  
            }  
            this.myDate = parseDate(p0, p1);  
        } else if (arguments.length == 0) {  
            this.myDate = new Date();  
        } else {  
            throw 'MyDate Constructor Error!';  
        }  
    };  
    /**  
     * @description 给一个日期设置年份  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setYearG(finalYear, mDate, self) {  
        mDate.setFullYear(finalYear);  
    }  
    /**  
     * @description 给一个日期设置月份  
     * 之所以要单独将设置月份(年,日,时...)的函数抽取出来,是因为  
     * 在日期时间 加,减操作时,会涉及到一个进位问题: 比如,1月31日的下一天应该是2月1日...  
     * 所以单独封装成函数便于调用  
     * 之所以没有 直接调用plusMonth,plusYear...  
     * 是因为这个操作中间有回调,多个回调嵌套后,无法同步返回最准确的数据  
     * (可以自行测试)  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setMonthG(finalMon, mDate, self) {  
        //month 为 0-11  
        if (finalMon > 11) {  
            finalMon = finalMon - 12;  
            setYearG(mDate.getFullYear() + 1, mDate, self);  
        } else if (finalMon < 0) {  
            finalMon += 12;  
            setYearG(mDate.getFullYear() - 1, mDate, self);  
        }  
        /*  
         * 关于月份顺延的bug  
         发现如下规律:只要setMonth()的参数为小于31天的月份时就会变为下一个月。  
          原因是:因为当前月份是31天,而设置的月份小于31天,就会把日期顺延。在setMonth的说明是这样的:  
          dateObj.setMonth(numMonth[, dateVal])  
          dateVal  
        可选项。一个代表日期的数值。  
        如果没有提供此参数,那么将使用通过调用 getDate 方法而得到的数值。  
        所以,从对dataVal参数的说明可以看出,在设置月份的同时,  
        使用getDate获取日期,并使用得到的日期值设置了日期。  
        于是就会发生月份顺延的情况。  
        解决方法:  
      1、设置月份时,将日期设为1,记setMonth(month, 1),  
      当然可以在setMonth之前先调用setDate()设置日期;  
      2、也可以在初始化Date对象时,就指定一个日期,也就是使用:  
      dateObj = new Date(year, month, date[, hours[, minutes[, seconds[,ms]]]]) 的形式。  
      3、也可以使用setFullYear()同时设置年、月、日,即setFullYear(numYear[, numMonth[, numDate]])。   
        *bug简单说明:  
        * 如果当前是10月31日,然后设置月份为11,由于11月没有31天,所以月份会顺延  
        * 自动变为12月,所以解决方法是要在设置月份前先把日期设置下,然后之后再继续设置日期  
        * (因为日期肯定是需要改变的)  
        *   
        * * * */  
        mDate.setMonth(finalMon, 1);  

    }  
    /**  
     * @description 给一个日期设置日期  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setDateG(finalDay, mDate, self) {  
        var month = mDate.getMonth();  
        var monthDays = self.getMonthDays(month + 1);  
        if (finalDay > monthDays) {  
            finalDay -= monthDays;  
            setMonthG(mDate.getMonth() + 1, mDate, self);  
        } else if (finalDay <= 0) {  
            var lastMonthDay = month > 0 ? self.getMonthDays((month + 1 - 1)) : self.getMonthDays(12);  
            finalDay += lastMonthDay;  
            setMonthG(mDate.getMonth() - 1, mDate, self);  
        }  
        mDate.setDate(finalDay);  
    }  
    /**  
     * @description 给一个日期设置小时  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setHourG(finalHour, mDate, self) {  
        if (finalHour >= 24) {  
            finalHour -= 24;  
            setDateG(mDate.getDate() + 1, mDate, self);  
        } else if (finalHour < 0) {  
            finalHour += 24;  
            setDateG(mDate.getDate() - 1, mDate, self);  
        }  
        mDate.setHours(finalHour);  
    }  
    /**  
     * @description 给一个日期设置分钟  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setMinG(finalMin, mDate, self) {  
        if (finalMin >= 60) {  
            finalMin -= 60;  
            setHourG(mDate.getHours() + 1, mDate, self);  
        } else if (finalHour < 0) {  
            finalMin += 60;  
            setHourG(mDate.getHours() - 1, mDate, self);  
        }  
        mDate.setMinutes(finalMin);  
    }  
    /**  
     * @description 给一个日期设置秒  
     * @param {Number} finalYear  
     * @param {Date} mDate  
     * @param {MyDate} self  
     */  
    function setSecG(finalSec, mDate, self) {  
        if (finalSec >= 60) {  
            finalSec -= 60;  
            setMinG(mDate.getMinutes() + 1, mDate, self);  
        } else if (finalSec < 0) {  
            finalSec += 60;  
            setMinG(mDate.getMinutes() - 1, mDate, self);  
        }  
        mDate.setSeconds(finalSec);  
    }  
    /**  
     * @description 通过扩充原型添加方法  
     */  
    MyDate.prototype = {  
        /**  
         * @description 得到一个月有多少天  
         * @param {Number} month 对应的月份  
         */  
        getMonthDays: function(month) {  
            switch (month) {  
                case 1:  
                case 3:  
                case 5:  
                case 7:  
                case 8:  
                case 10:  
                case 12:  
                    return 31;  
                    break;  
                case 4:  
                case 6:  
                case 9:  
                case 11:  
                    return 30;  
                    break;  
                case 2:  
                    if (this.isLeapYear()) {  
                        return 29;  
                    } else {  
                        return 28;  
                    }  
                    break;  
                default:  
                    return 0;  
                    break;  
            }  
        },  
        /**  
         * @description 年份相加,返回一个新的日期  
         * @param {Object} value  
         */  
        plusYear: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                setYearG(year + value, mDate, self);  
            }));  
        },  
        plusMonth: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                setMonthG(month + value, mDate, self);  
            }));  
        },  
        plusDate: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalDay = date + value;  
                setDateG(finalDay, mDate, self);  
            }));  
        },  
        plusHours: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalHour = hours + value;  
                setHourG(finalHour, mDate, self);  
            }));  
        },  
        plusMinutes: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalMin = minutes + value;  
                setMinG(finalMin, mDate, self);  
            }));  
        },  
        plusSeconds: function(value) {  
            var self = this;  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                var finalSec = seconds + value;  
                setSecG(finalSec, mDate, self);  
            }));  
        },  
        minusYear: function(value) {  
            return this.plusYear(-value);  
        },  
        minusMonth: function(value) {  
            return this.plusMonth(-value);  
        },  
        minusDate: function(value) {  
            return this.plusDate(-value);  
        },  
        minusHours: function(value) {  
            return this.plusHours(-value);  
        },  
        minusMinutes: function(value) {  
            return this.plusMinutes(-value);  
        },  
        minusSeconds: function(value) {  
            return this.plusSeconds(-value);  
        },  
        setYear: function(value) {  
            this.myDate.setFullYear(value);  
        },  
        setMonth: function(value) {  
            this.myDate.setMonth(value - 1);  
        },  
        setDate: function(value) {  
            this.myDate.setDate(value);  
        },  
        setHours: function(value) {  
            this.myDate.setHours(value);  
        },  
        setMinutes: function(value) {  
            this.myDate.setMinutes(value);  
        },  
        setSeconds: function(value) {  
            this.myDate.setSeconds(value);  
        },  
        setMilliseconds: function(value) {  
            this.myDate.setMilliseconds(value);  
        },  
        getYear: function() {  
            return this.myDate.getFullYear();  
        },  
        getMonth: function() {  
            //比普通月份小1  
            return this.myDate.getMonth();  
        },  
        getDate: function() {  
            return this.myDate.getDate();  
        },  
        getHours: function() {  
            return this.myDate.getHours();  
        },  
        getMinutes: function() {  
            return this.myDate.getMinutes();  
        },  
        getSeconds: function() {  
            return this.myDate.getSeconds();  
        },  
        getMilliseconds: function() {  
            return this.myDate.getMilliseconds();  
        },  
        /**  
         * @description 得到从1970至今多少年  
         */  
        getAbsoluteYear: function() {  
            return this.myDate.getFullYear() - 1970;  
        },  
        getAbsoluteMonth: function() {  
            return this.getAbsoluteYear() * 12 + this.myDate.getMonth();  
        },  
        /**  
         * @description 获得绝对日期  
         * 这里采取的方法为 得到从1970至今的毫秒数,然后转为天  
         */  
        getAbsoluteDate: function() {  
            var absoluteMillons = this.getAbsoluteMillonsTime();  
            //毫秒-秒-分-时-天  
            return parseInt(absoluteMillons / 1000 / 60 / 60 / 24, 10);  
        },  
        getAbsoluteHours: function() {  
            return this.getAbsoluteDate() * 24 + this.myDate.getHours();  
        },  
        getAbsoluteMinutes: function() {  
            return this.getAbsoluteHours() * 60 + this.myDate.getMinutes();  
        },  
        getAbsoluteSeconds: function() {  
            return this.getAbsoluteMinutes() * 60 + this.myDate.getSeconds();  
        },  
        /**  
         * @description 得到从1970年开始到现在的毫秒数  
         * 单位是毫秒  
         */  
        getAbsoluteMillonsTime: function() {  
            return this.myDate.getTime();  
        },  
        getDayOfWeek: function(pattern) {  
            //0(周日) 到 6(周六  
            //var week = ['日','一','二','三','四','五','六'];  
            return this.myDate.getDay();  
        },  
        isLeapYear: function() {  
            return (0 == this.myDate.getYear() % 4 && ((this.myDate.getYear() % 100 != 0) || (this.myDate.getYear() % 400 == 0)));  
        },  
        toDate: function() {  
            return cloneDate(this.myDate);  
        },  
        clone: function() {  
            return new MyDate(cloneDate(this.myDate));  
        },  
        /**  
         * @description 得到一个日期的最小时间  
         * @param {String}method = [YYYY|MM|DD|hh|mm|ss] field 分别代表年,月,日,时,分,秒的抉择  
         */  
        getBegin: function(field) {  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                switch (field) {  
                    case 'YYYY': //year  
                        mDate.setMonth(0);  
                        mDate.setDate(1);  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'MM': //month  
                        mDate.setDate(1);  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                    case 'DD': //date  
                        mDate.setHours(0);  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'hh': //hour  
                        mDate.setMinutes(0);  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'mm': //minute  
                        mDate.setSeconds(0);  
                        mDate.setMilliseconds(0);  
                        break;  
                    case 'ss': //seconds  
                        mDate.setMilliseconds(0);  
                        break;  
                    default:  
                        //Ignore  
                }  
            }));  
        },  
        /**  
         * @description 得到一个日期的最大时间  
         * @param {String}method = [YYYY|MM|DD|hh|mm|ss] field 分别代表年,月,日,时,分,秒的抉择  
         */  
        getEnd: function(field) {  
            return new MyDate(cloneDate(this.myDate, function(mDate, year, month, date, hours, minutes, seconds) {  
                switch (field) {  
                    case 'YYYY': //year  
                        mDate.setMonth(11);  
                        mDate.setDate(31);  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'MM': //month  
                        mDate.setDate(getActualMaximum(mDate));  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                    case 'DD': //date  
                        mDate.setHours(23);  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'hh': //hour  
                        mDate.setMinutes(59);  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'mm': //minute  
                        mDate.setSeconds(59);  
                        mDate.setMilliseconds(999);  
                        break;  
                    case 'ss': //seconds  
                        mDate.setMilliseconds(999);  
                        break;  
                    default:  
                        //Ignore  
                }  
            }));  
        },  
        /**  
         * @description 和另一个日期比较,另一个日期必须为MyDate型  
         * @param {Date} targetDate 目标日期,MyDate型  
         * @param {String} method = [YYYY|MM|DD|hh|mm|ss|iii] pettern 选择字符串,目前支持 yyyy,MM,dd,HH,mm,ss以及iii  
         * 分别代表比较到某一个层次,默认为比较到毫秒  
         * @return {Number} 返回结果  
         * -1:比较字符对象不合法  
         * 0:两个日期相等  
         * 1:本日期大于目标日期  
         * 2:本日期小于目标日期  
         */  
        compare: function(targetDate, pattern) {  
            //如果不是时间类型,而且不是MyDate类型  
            if (!isDate(targetDate) && !(targetDate instanceof MyDate)) {  
                return -1;  
            }  
            //默认为毫秒  
            pattern = pattern || 'iii';  
            if (pattern === 'YYYY') {  
                if (this.getAbsoluteYear() == targetDate.getAbsoluteYear()) {  
                    return 0;  
                } else if (this.getAbsoluteYear() > targetDate.getAbsoluteYear()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'MM') {  
                if (this.getAbsoluteMonth() == targetDate.getAbsoluteMonth()) {  
                    return 0;  
                } else if (this.getAbsoluteMonth() > targetDate.getAbsoluteMonth()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'DD') {  
                if (this.getAbsoluteDate() == targetDate.getAbsoluteDate()) {  
                    return 0;  
                } else if (this.getAbsoluteDate() > targetDate.getAbsoluteDate()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'hh') {  
                if (this.getAbsoluteHours() == targetDate.getAbsoluteHours()) {  
                    return 0;  
                } else if (this.getAbsoluteHours() > targetDate.getAbsoluteHours()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'mm') {  
                if (this.getAbsoluteMinutes() == targetDate.getAbsoluteMinutes()) {  
                    return 0;  
                } else if (this.getAbsoluteMinutes() > targetDate.getAbsoluteMinutes()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else if (pattern === 'ss') {  
                if (this.getAbsoluteSeconds() == targetDate.getAbsoluteSeconds()) {  
                    return 0;  
                } else if (this.getAbsoluteSeconds() > targetDate.getAbsoluteSeconds()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            } else {  
                if (this.getAbsoluteMillonsTime() == targetDate.getAbsoluteMillonsTime()) {  
                    return 0;  
                } else if (this.getAbsoluteMillonsTime() > targetDate.getAbsoluteMillonsTime()) {  
                    return 1;  
                } else {  
                    return 2;  
                }  
            }  
        },  
        isMoreThan: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 1 ? true : false;  
        },  
        isLessThan: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 2 ? true : false;  
        },  
        isEqual: function(targetDate, pattern) {  
            return this.compare(targetDate, pattern) == 0 ? true : false;  
        },  
        toString: function(pattern) {  
            return formatDateToString(this.myDate, pattern);  
        }  
    };  
    exports.MyDate = MyDate;       
})(window.DateUtil={});
收起阅读 »