
闹铃提醒
项目需要,做了一个闹铃提醒的例子。
<!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游戏提供了什么?
- 更高效的发行平台和留存率提升
通过DCloud与应用市场的合作,流应用可发行到应用市场里,并基于DCloud的流式发行技术实现秒开,过去App下载、安装、启动这3步被合为一步。
并且自动在桌面留存图标,不像浏览器那样是需要用户操作后才能创建到桌面上。这切实提高了留存率。 - 联合登陆-提升注册转化率
通过流应用提供的联合登陆机制,可直接完成注册,避免用户注册账户的麻烦,白名单合作厂商还可以直接拿到手机号。
这个机制可以切实提高注册转化率。
以传奇世界H5的运行数据为例,流应用版的角色创建率比各版平均值提升75%。 - 原生支付控件-提升支付成功率
在流应用平台里可以直接调起支付宝原生支付控件,如果开发商有微信wap支付权限,也可以直接在流应用里使用。
通过更优秀的体验,可以提高支付成功率。
以传奇世界H5的运行数据为例,流应用版的付费率比各版平均值提升100%,付费成功率提升50%。 - 社交分享-提升二次传播率
流应用提供的社交分享能力,可以调起原生的微信、微博、qq、短信、邮件等各种社交分享通道,方便的邀请好友和传播。
分享出去的链接别人点击后,如果手机上有流应用引擎,则会直接秒装好该游戏的流应用并进入特定界面,如果对方手机上没有流应用引擎则出现标准HTML5版本。
注:流应用引擎的装机覆盖量过亿,目前测试数据是每3个Android设备就有一个能命中。
通过流应用的分享机制,可以切实提高二次传播率。 - 更多操作系统的原生API
事实上除了上面常用的增强API,流应用提供了原生操作系统40万API的调用能力,完全可以在流应用里随意调用原生API。
开发者可以充分发挥想象力,摇一摇、扫一扫、原生定位、读取imei、back按键控制、软键盘控制、横竖屏控制、原生音频播放、前后台切换事件...
流应用没有提供什么?
流应用没有提供canvas加速器,所以裸奔体验也不错的游戏上流应用比较合适。
综上,可以看出流应用除了提供40万原生api外,在游戏的发行、留存、注册转换、支付、二次传播等方面均进行了强化处理,提升游戏的关键运营数据表现,并且在传奇世界H5的运行中用数据证明了提升效果。
那么如果你拥有一个裸奔体验不错的H5游戏,如何改造成流应用?
基本原则是你需要新建一个流应用微端项目,把微端项目提交到流应用平台,在微端项目里打开在线的H5 URL。
- 在http://DCloud.io下载HBuilder工具。这个工具是通用HTML5编辑器,App和web都可以开发。
- 在HBuilder里面新建一个移动App项目,打开里面的manifest.json,配好游戏的名称、ico、splash封面图片、splash手动关闭、全屏、设置硬件加速强制打开,参考http://ask.dcloud.net.cn/article/94。
- 在index.html里跳转到目前的H5的网络URL。
- 点菜单发行-发行流应用,根据提示操作。
- 然后把H5游戏的现有项目也拖到HBuilder里,成为一个普通的web项目。
- 在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时退出。 - 根据流应用的UA来让这些js生效,流应用的ua里包含“StreamApp”字符串,如果要打包为apk或ipa发行,则ua包含"Html5Plus"字符串。其实不管是流应用发行还是原生包发行,只要使用DCloud的客户端引擎ua里就会有"Html5Plus"字符串,同时在流应用模型是ua多增加了“StreamApp”字符串。
- 特别要注意一点,大多数H5游戏都有一个网络加载的首屏,即先从服务器取一个首屏等待界面,然后后台继续载资源直到游戏可以进入。
但在流应用里,这个模式不对。
流应用splash封面图是本地化的,已经配在了manifest里,此时服务器不需要再请求一个等待界面,多浪费用户流量和增加等待时间。
也就是从桌面点图标时,流应用与原生app一样是先启动本地splash封面图,然后等待游戏进入,游戏进入后再调用plus.navigator.closeSplashscreen()关闭splash图片即可。 - 还可以在你的H5游戏里内嵌一个gostream.js,在非流应用的环境下引入,这个js可以检测手机上是否有流应用引擎,如果有则可以秒开流应用,实现wap流量转换为app流量。参考http://ask.dcloud.net.cn/article/579
以上工作中,涉及增强api调用的工作并不是强制的,不调用也可以申请上线,就是一个普通的H5页游。
但这些增强api不调用,将影响数据转换。
流应用QQ交流群,请加:471285299。
传统的H5游戏,只能在浏览器里发行,不能在应用市场发行,也无法自动在桌面留有图标。
这样的H5游戏,体验不足,留存上不去。
流应用不是在浏览器里发行,而是在应用市场发行,在桌面天然有图标,但却也拥有即点即开的特性。
并且运行在流应用里,可以调用操作系统底层的40w api,可实现强大的功能。
下图为在360手机助手搜索传奇世界,可看到流应用的秒开按钮。
流应用为H5游戏提供了什么?
- 更高效的发行平台和留存率提升
通过DCloud与应用市场的合作,流应用可发行到应用市场里,并基于DCloud的流式发行技术实现秒开,过去App下载、安装、启动这3步被合为一步。
并且自动在桌面留存图标,不像浏览器那样是需要用户操作后才能创建到桌面上。这切实提高了留存率。 - 联合登陆-提升注册转化率
通过流应用提供的联合登陆机制,可直接完成注册,避免用户注册账户的麻烦,白名单合作厂商还可以直接拿到手机号。
这个机制可以切实提高注册转化率。
以传奇世界H5的运行数据为例,流应用版的角色创建率比各版平均值提升75%。 - 原生支付控件-提升支付成功率
在流应用平台里可以直接调起支付宝原生支付控件,如果开发商有微信wap支付权限,也可以直接在流应用里使用。
通过更优秀的体验,可以提高支付成功率。
以传奇世界H5的运行数据为例,流应用版的付费率比各版平均值提升100%,付费成功率提升50%。 - 社交分享-提升二次传播率
流应用提供的社交分享能力,可以调起原生的微信、微博、qq、短信、邮件等各种社交分享通道,方便的邀请好友和传播。
分享出去的链接别人点击后,如果手机上有流应用引擎,则会直接秒装好该游戏的流应用并进入特定界面,如果对方手机上没有流应用引擎则出现标准HTML5版本。
注:流应用引擎的装机覆盖量过亿,目前测试数据是每3个Android设备就有一个能命中。
通过流应用的分享机制,可以切实提高二次传播率。 - 更多操作系统的原生API
事实上除了上面常用的增强API,流应用提供了原生操作系统40万API的调用能力,完全可以在流应用里随意调用原生API。
开发者可以充分发挥想象力,摇一摇、扫一扫、原生定位、读取imei、back按键控制、软键盘控制、横竖屏控制、原生音频播放、前后台切换事件...
流应用没有提供什么?
流应用没有提供canvas加速器,所以裸奔体验也不错的游戏上流应用比较合适。
综上,可以看出流应用除了提供40万原生api外,在游戏的发行、留存、注册转换、支付、二次传播等方面均进行了强化处理,提升游戏的关键运营数据表现,并且在传奇世界H5的运行中用数据证明了提升效果。
那么如果你拥有一个裸奔体验不错的H5游戏,如何改造成流应用?
基本原则是你需要新建一个流应用微端项目,把微端项目提交到流应用平台,在微端项目里打开在线的H5 URL。
- 在http://DCloud.io下载HBuilder工具。这个工具是通用HTML5编辑器,App和web都可以开发。
- 在HBuilder里面新建一个移动App项目,打开里面的manifest.json,配好游戏的名称、ico、splash封面图片、splash手动关闭、全屏、设置硬件加速强制打开,参考http://ask.dcloud.net.cn/article/94。
- 在index.html里跳转到目前的H5的网络URL。
- 点菜单发行-发行流应用,根据提示操作。
- 然后把H5游戏的现有项目也拖到HBuilder里,成为一个普通的web项目。
- 在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时退出。 - 根据流应用的UA来让这些js生效,流应用的ua里包含“StreamApp”字符串,如果要打包为apk或ipa发行,则ua包含"Html5Plus"字符串。其实不管是流应用发行还是原生包发行,只要使用DCloud的客户端引擎ua里就会有"Html5Plus"字符串,同时在流应用模型是ua多增加了“StreamApp”字符串。
- 特别要注意一点,大多数H5游戏都有一个网络加载的首屏,即先从服务器取一个首屏等待界面,然后后台继续载资源直到游戏可以进入。
但在流应用里,这个模式不对。
流应用splash封面图是本地化的,已经配在了manifest里,此时服务器不需要再请求一个等待界面,多浪费用户流量和增加等待时间。
也就是从桌面点图标时,流应用与原生app一样是先启动本地splash封面图,然后等待游戏进入,游戏进入后再调用plus.navigator.closeSplashscreen()关闭splash图片即可。 - 还可以在你的H5游戏里内嵌一个gostream.js,在非流应用的环境下引入,这个js可以检测手机上是否有流应用引擎,如果有则可以秒开流应用,实现wap流量转换为app流量。参考http://ask.dcloud.net.cn/article/579
以上工作中,涉及增强api调用的工作并不是强制的,不调用也可以申请上线,就是一个普通的H5页游。
但这些增强api不调用,将影响数据转换。
流应用QQ交流群,请加:471285299。
收起阅读 »
在哪里学习跨平台app开发、HBuilder、MUI的课程?
在今年这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些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的时候左边有个折叠代码的功能,用基本上一个标签一个折叠按钮,但是当我下载了php插件之后就不能折叠代码,只有html5的头文件那里有一个折叠的按钮其他的标签都没有是什么问题
因为代码敲击的多了,想转回去改一些css 都得重新去找,如果没有折叠标签会很浪费时间!!!
各位大神我是> 小白 你们现在讨论的都感觉好高大上 我劳烦你们看下我的问题 我就想请教一个 Hbuilder在编写html5的时候左边有个折叠代码的功能,用基本上一个标签一个折叠按钮,但是当我下载了php插件之后就不能折叠代码,只有html5的头文件那里有一个折叠的按钮其他的标签都没有是什么问题
因为代码敲击的多了,想转回去改一些css 都得重新去找,如果没有折叠标签会很浪费时间!!!

【分享】JS 日期工具类-基于yDate
前言:最近在用到JS日期操作时,发现有一些不方便,于是搜素了一些网上的资料,基于一个开源工具类-yDate 进行了个性化定制,封装成了一个日期工具类
工具函数大概介绍:
1.普通的日期操作
- 获得一些绝对时间,如1970年 到现在的绝对年,月份,日期,描述,毫秒数等等
- 日期比较,克隆,开始时间,结束时间,字符串(输出时可以自定义格式)输出等
- 日期相加,相减(返回一个新的日期对象), 比如1月31日 1天会自动变为 2月1日等等
- 简化构造,可以传入字符串进行构造等等
- 更多请看源码
说明-基于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.普通的日期操作
- 获得一些绝对时间,如1970年 到现在的绝对年,月份,日期,描述,毫秒数等等
- 日期比较,克隆,开始时间,结束时间,字符串(输出时可以自定义格式)输出等
- 日期相加,相减(返回一个新的日期对象), 比如1月31日 1天会自动变为 2月1日等等
- 简化构造,可以传入字符串进行构造等等
- 更多请看源码
说明-基于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={});
收起阅读 »

分享移动端图片压缩上传(整理修改微社区图片上传,带UI,带demo,demo服务器端用php)
20160411更新:
使同个页面可以配置调用多个上传图片
20160418更新:
修复上传进度条不准
增加上传样式2,调整部分样式
一些配置问题:
objUploadImg.uploadMaxW = 2000; //生成图片的最大宽度
objUploadImg.uploadMaxH = 2000; //生成图片的最大高度
*建议这两项默认800800
objUploadImg.uploadPicMore = true;//是否允许多图上传 默认单张上传
即便开启,安卓也只支持单张上传
objUploadImg.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
最好不要过多,因为图片在前端用H5 <canvas> 处理,测试过配置最大宽高为2000px时,iPhone6微信端一次上传20张会出现微信自动关闭;如果同个页面调用多个上传方法,一次上传的最大张数之和最好不超过10张**
其他的自行查看附件demo,随便贴几段代码,注意JS代码的引用位置
<!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" href="css/mobile-uploadImg.css">
<script src="js/jquery-1.9.0.js"></script>
<script src="js/mobile-uploadCompresserImg.js"></script>
<script src="js/mobile-uploadImg.js"></script>
</head>
<body style="background: #f5f5f5;">
<div style="margin:20px 10px;">
<form method="post" action="">
<div id="uploadImgForm">
<div class="mbupload_frame">
<div class="mbupload_photoList">
<ul>
<li class="mbupload_on mbupload_addPic mbupload_addImg"></li>
</ul>
<p class="mbupload_textTip mbupload_f12">还可上传<span class="mbupload_onlyUploadNum"></span>张照片呦~</p>
</div>
<div class="mbupload_bgimg">
<div class="iconSendImg mbupload_addImg" style="background:url(images/upload_carbg.png) no-repeat 50% 50%;"></div>
</div>
</div>
</div>
<div style="margin-top:20px;">
<div id="uploadImgForm2" class="uploadImgStyle2">
<div class="mbupload_frame">
<div class="mbupload_photoList">
<ul>
<li class="mbupload_on mbupload_addPic mbupload_addImg"></li>
</ul>
<p class="mbupload_textTip mbupload_f12">还可上传<span class="mbupload_onlyUploadNum"></span>张照片呦~</p>
</div>
<div class="mbupload_bgimg">
<div class="iconSendImg mbupload_addImg" style="background:url(images/upload_licensebg.png) no-repeat 50% 50%;"></div>
</div>
</div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
var objUploadImgForm = {};
objUploadImgForm.uploadUrl = "<?php echo('http://'.$_SERVER['HTTP_HOST'].'/uploads.php') ?>";//上传图片的地址
objUploadImgForm.formHtmlId = "#uploadImgForm";//上传图片的ID
objUploadImgForm.maxUpload = 20;//上传图片的最大张数
objUploadImgForm.uploadMaxW = 2000; //生成图片的最大宽度
objUploadImgForm.uploadMaxH = 2000; //生成图片的最大高度
objUploadImgForm.uploadQuality = 1; //目标jpg图片输出质量
objUploadImgForm.uploadPicSize = 8;//上传限制图片大小(MB) 默认8M
objUploadImgForm.uploadPicMore = true;//是否允许多图上传 默认单张上传
objUploadImgForm.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
objUploadImgForm.uploadDefaultImgUrl = "images/defaultImg.png";//压缩图片时的默认图片地址
mobileUploadImg(objUploadImgForm);
</script>
<script type="text/javascript">
var objUploadImgForm2 = {};
objUploadImgForm2.uploadUrl = "<?php echo('http://'.$_SERVER['HTTP_HOST'].'/uploads.php') ?>";//上传图片的地址
objUploadImgForm2.formHtmlId = "#uploadImgForm2";//上传图片的ID
objUploadImgForm2.maxUpload = 1;//上传图片的最大张数
objUploadImgForm2.uploadMaxW = 800; //生成图片的最大宽度
objUploadImgForm2.uploadMaxH = 800; //生成图片的最大高度
objUploadImgForm2.uploadQuality = 1; //目标jpg图片输出质量
objUploadImgForm2.uploadPicSize = 8;//上传限制图片大小(MB) 默认8M
objUploadImgForm2.uploadPicMore = true;//是否允许多图上传 默认单张上传
objUploadImgForm2.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
objUploadImgForm2.uploadDefaultImgUrl = "images/defaultImg.png";//压缩图片时的默认图片地址
mobileUploadImg(objUploadImgForm2);
</script>
</body>
</html>
/**
* @filename mobile-uploadImg
* @description
* 作者: 418239385(418239385@qq.com)
* 创建时间: 2016-4-6 14:38:03
* 修改记录:
*
**/
//------------------------------------------------------------------------------
function mobileUploadImg(opts)
{
if(opts == null){
objGlobal.DIC.dialog({content:'请配置上传图片的相关参数!', autoClose:false, okValue:"确定", isMask:true});
return;
}
var objUploadImg = {};
var opts = opts || {};
//上传图片的表单ID
objUploadImg.formHtmlId = opts.formHtmlId || "";
//最大上传图片量
objUploadImg.maxUpload = opts.maxUpload || 8;
//生成图片的最大宽度
objUploadImg.uploadMaxW = opts.uploadMaxW || 800;
//生成图片的最大高度
objUploadImg.uploadMaxH = opts.uploadMaxH || 800;
//目标jpg图片输出质量
objUploadImg.uploadQuality = opts.uploadQuality || 1;
//上传限制图片体积(MB) 默认8M
objUploadImg.uploadPicSize = opts.uploadPicSize || 8;
//是否允许多图上传 默认单张上传
objUploadImg.uploadPicMore = opts.uploadPicMore || false;
//多图上传时,一次上传的最大张数 默认10
objUploadImg.onceMaxUpload = opts.onceMaxUpload || 10;
// 上传图片地址
objUploadImg.uploadUrl = opts.uploadUrl || "";
//压缩图片时的默认图片地址
objUploadImg.uploadDefaultImgUrl = opts.uploadDefaultImgUrl || "";
//多图上传时,上传第一张到最后一张的状态
objUploadImg.isMoreBusy = false;
// 上传信息 主要是 id 对应信息
objUploadImg.uploadInfo = {};
// 上传队列,里面保存的是 id
objUploadImg.uploadQueue = [];
// 预览队列,里面保存的是 id
objUploadImg.previewQueue = [];
// 请求对象
objUploadImg.xhr = {};
// 是否有图片正在压缩
objUploadImg.isEncoderBusy = false;
// 是否有任务正在上传
objUploadImg.isBusy = false;
if(objUploadImg.formHtmlId.length <= 0){
objGlobal.DIC.dialog({content:'请配置上传图片的容器ID!', autoClose:false, okValue:"确定", isMask:true});
return;
}
if(objUploadImg.uploadUrl.length <= 0){
objGlobal.DIC.dialog({content:'请配置上传图片的URL地址!', autoClose:false, okValue:"确定", isMask:true});
return;
}
objUploadImg.countUpload = function() {
var num = 0;
$.each(objUploadImg.uploadInfo, function(i, n) {
if (n) {
++ num;
}
});
return num;
};
// 图片预览
objUploadImg.uploadPreview = function(id) {
var reader = new FileReader();
var uploadBase64;
var conf = {}, file = objUploadImg.uploadInfo[id].file;
conf = {
maxW: objUploadImg.uploadMaxW, //目标宽
maxH: objUploadImg.uploadMaxH, //目标高
quality: objUploadImg.uploadQuality, //目标jpg图片输出质量
};
reader.onload = function(e) {
var result = this.result;
// 如果是jpg格式图片,读取图片拍摄方向,自动旋转
if (file.type == 'image/jpeg'){
try {
var jpg = new objJpegMeata.JpegMeta.JpegFile(result, file.name);
} catch (e) {
objGlobal.DIC.dialog({content:'图片不是正确的图片数据', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
if (jpg.tiff && jpg.tiff.Orientation) {
//设置旋转
conf = $.extend(conf, {
orien: jpg.tiff.Orientation.value
});
}
}
// 压缩
if (objImageCompresser.ImageCompresser.support()) {
var img = new Image();
img.onload = function() {
try {
uploadBase64 = objImageCompresser.ImageCompresser.getImageBase64(this, conf);
} catch (e) {
objGlobal.DIC.dialog({content:'压缩图片失败', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
if (uploadBase64.indexOf('data:image') < 0) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
objUploadImg.uploadInfo[id].file = uploadBase64;
$(objUploadImg.formHtmlId + ' #li' + id).find('img').attr('src', uploadBase64);
objUploadImg.uploadQueue.push(id);
}
img.onerror = function() {
objGlobal.DIC.dialog({content:'解析图片数据失败', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
img.src = objImageCompresser.ImageCompresser.getFileObjectURL(file);
} else {
uploadBase64 = result;
if (uploadBase64.indexOf('data:image') < 0) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
objUploadImg.uploadInfo[id].file = uploadBase64;
$(objUploadImg.formHtmlId + ' #li' + id).find('img').attr('src', uploadBase64);
objUploadImg.uploadQueue.push(id);
}
}
reader.readAsBinaryString(objUploadImg.uploadInfo[id].file);
};
// 创建上传请求
objUploadImg.createUpload = function(id, type, uploadTimer) {
if (!objUploadImg.uploadInfo[id]) {
objUploadImg.isEncoderBusy = false;
objUploadImg.isBusy = false;
return false;
}
// 移除图片压缩中...
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskTxt').remove();
// 图片posturl
var uploadUrl = objUploadImg.uploadUrl;
// 产生进度条
var progressHtml = '<div class="mbupload_progress mbupload_brSmall" id="mbupload_progress'+id+'"><div class="mbupload_proBar" style="width:0%;"></div></div>';
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskLay').after(progressHtml);
var formData = new FormData();
formData.append('upload_pic', objUploadImg.uploadInfo[id].file);
formData.append('upload_name', objUploadImg.uploadInfo[id].oldFileInfo.name);
formData.append('upload_id', id);
var progress = function(e) {
if (e.target.response) {
var result = $.parseJSON(e.target.response);
if (result.errCode != 0) {
// $('#content').val(result.errCode);
objGlobal.DIC.dialog({content:'网络不稳定,请稍后重新操作', autoClose:true});
removePic(id);
//更新剩余上传数
objUploadImg.uploadRemaining();
return false;
}
}
var progress = $(objUploadImg.formHtmlId + ' #mbupload_progress' + id).find('.mbupload_proBar');
if (e.total == e.loaded) {
var percent = 100;
} else {
var percent = 100*(e.loaded / e.total);
}
// 控制进度条不要超出
if (percent > 100) {
percent = 100;
}
progress.width(percent + '%');
//progress.animate({'width': '95%'}, 1500);
setTimeout(function(){
if (percent == 100) {
donePic(id);
var pLength = 0, nLength = 0;
if(objUploadImg.uploadPicMore){
pLength = objUploadImg.previewQueue.length;
nLength = objUploadImg.uploadQueue.length;
}
if(uploadTimer && pLength <= 0 && nLength <= 0){
clearInterval(uploadTimer);
}
}
}, 400);
}
var removePic = function(id) {
donePic(id);
$('#li' + id).remove();
}
var donePic = function(id) {
objUploadImg.isEncoderBusy = false;
objUploadImg.isBusy = false;
if(objUploadImg.uploadPicMore && (objUploadImg.previewQueue.length <= 0) &&
(objUploadImg.uploadQueue.length <= 0)){
objUploadImg.isMoreBusy = false;
}
if (typeof objUploadImg.uploadInfo[id] != 'undefined') {
objUploadImg.uploadInfo[id].isDone = true;
}
if (typeof objUploadImg.xhr[id] != 'undefined') {
objUploadImg.xhr[id] = null;
}
}
var complete = function(e) {
var progress = $(objUploadImg.formHtmlId + ' #mbupload_progress' + id).find('.mbupload_proBar');
progress.css('width', '100%');
if($(objUploadImg.formHtmlId + ' #li' + id)){
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskTxt').remove();
}
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskLay').remove();
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_progress').remove();
// 上传结束
donePic(id);
var result = $.parseJSON(e.target.response);
if (result.errCode == 0) {
var input = '<input type="hidden" id="input' + result.data.id + '" name="picIds[]" value="' + result.data.picId + '">';
if(type == 'replyForm'){
$('#replyForm').append(input);
}else{
$(objUploadImg.formHtmlId).append(input);
}
} else {
objGlobal.DIC.dialog({content:'网络不稳定,请稍后重新操作', autoClose:true});
removePic(id);
//更新剩余上传数
objUploadImg.uploadRemaining();
delete objUploadImg.uploadInfo[id];
// 如果传略失败,上传个数少于限制张数则再显示加号
if (objUploadImg.countUpload() < objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').show();
}
}
}
var failed = function() {
objGlobal.DIC.dialog({content:'网络断开,请稍后重新操作', autoClose:true});
removePic(id)
}
var abort = function() {
objGlobal.DIC.dialog({content:'上传已取消', autoClose:true});
removePic(id)
}
// 创建 ajax 请求
objUploadImg.xhr[id] = new XMLHttpRequest();
objUploadImg.xhr[id].addEventListener("progress", progress, false);
objUploadImg.xhr[id].upload.addEventListener("progress", progress, false);
objUploadImg.xhr[id].addEventListener("load", complete, false);
objUploadImg.xhr[id].addEventListener("abort", abort, false);
objUploadImg.xhr[id].addEventListener("error", failed, false);
objUploadImg.xhr[id].open("POST", uploadUrl);
objUploadImg.xhr[id].send(formData);
};
// 不能上传系统提示
objUploadImg.checkUploadBySysVer = function() {
var mb_os = objGlobal.checkUA();
if (mb_os.ios && mb_os.version.toString() < '6.0') {
objGlobal.DIC.dialog({content:'手机系统不支持传图,请升级到ios6.0以上', autoClose:true});
return false;
}
if (mb_os.wx && mb_os.wxVersion.toString() < '5.2') {
objGlobal.DIC.dialog({content:'当前微信版本不支持传图,请升级到最新版', autoClose:true});
return false;
}
return true;
};
//根据是否可以多图上传生成对应的input
objUploadImg.uploadAddInput = function(){
var input = "", fistInput = "";
if(objUploadImg.uploadPicMore){
input = '<input type="file" class="mbupload_on mbupload_uploadFile" accept="image/*" multiple="">';
fistInput = '<input type="file" class="fistUpload" accept="image/*" multiple="">';
}else{
input = '<input type="file" class="mbupload_on mbupload_uploadFile" accept="image/*" single="">';
fistInput = '<input type="file" class="fistUpload" accept="image/*" single="">';
}
$(objUploadImg.formHtmlId + ' .mbupload_addPic').append(input);
$(objUploadImg.formHtmlId + ' .iconSendImg').append(fistInput);
};
//剩余上传数
objUploadImg.uploadRemaining = function(){
var uploadNum = 0;
uploadNum = $(objUploadImg.formHtmlId + ' .mbupload_photoList').find('li').length;
var canOnlyUploadNum = objUploadImg.maxUpload;
if(uploadNum <= objUploadImg.maxUpload)
{
canOnlyUploadNum = objUploadImg.maxUpload - uploadNum + 1;
}
else
{
canOnlyUploadNum = 0;
}
//当上传出错则显示第一上传页面
if(canOnlyUploadNum == objUploadImg.maxUpload)
{
$(objUploadImg.formHtmlId + ' .mbupload_photoList').hide();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').show();
}
//更新剩余可上传图片数
$(objUploadImg.formHtmlId + ' .mbupload_onlyUploadNum').html(canOnlyUploadNum);
};
// 检查图片大小
objUploadImg.checkPicSize = function(file) {
var uploadPicSize = objUploadImg.uploadPicSize*1024*1024;
if (file.size > uploadPicSize) {
return false;
}
return true;
};
// 检查图片类型
objUploadImg.checkPicType = function(file) {
var photoReg = (/\.png$|\.bmp$|\.jpg$|\.jpeg$|\.gif$/i);
if(!photoReg.test(file.name)){
return false;
}else{
return true;
}
};
var uploadTimer = null;
var initUpload = function()
{
// 上传图片的绑定
$(objUploadImg.formHtmlId + ' .mbupload_addImg').on("click", function(){
if(!objUploadImg.checkUploadBySysVer()){
return false;
}
});
$(objUploadImg.formHtmlId + ' .mbupload_uploadFile').on("click", function(){
var thisObj = $(this);
if (objUploadImg.isEncoderBusy) {
return false;
}
else if (objUploadImg.isBusy) {
objGlobal.DIC.dialog({content:'上传中,请稍后添加', autoClose:true});
return false;
}
else if (objUploadImg.isMoreBusy) {
objGlobal.DIC.dialog({content:'上传中,请稍后添加', autoClose:true});
return false;
}
});
//首次点击图片的图标,触发一次手机的默认上传事件
$('body').on('change', objUploadImg.formHtmlId + ' .fistUpload', function(e){
$(objUploadImg.formHtmlId + ' .mbupload_photoList').show();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').hide();
});
// 文件表单发生变化时
$('body').on('change', objUploadImg.formHtmlId + ' .mbupload_uploadFile,' + objUploadImg.formHtmlId + ' .fistUpload', function(e) {
//执行图片预览、压缩定时器
uploadTimer = setInterval(function() {
// 预览
setTimeout(function() {
if (!objUploadImg.isEncoderBusy && objUploadImg.previewQueue.length) {
var jobId = objUploadImg.previewQueue.shift();
objUploadImg.isEncoderBusy = true;
objUploadImg.uploadPreview(jobId);
}
}, 1);
// 上传
setTimeout(function() {
if (!objUploadImg.isBusy && objUploadImg.uploadQueue.length) {
var jobId = objUploadImg.uploadQueue.shift();
objUploadImg.isBusy = true;
if(objUploadImg.uploadPicMore){
objUploadImg.isMoreBusy = true;
}
objUploadImg.createUpload(jobId, objUploadImg.formHtmlId, uploadTimer);
}
}, 10);
}, 300);
e = e || window.event;
var fileList = e.target.files;
if (!fileList.length) {
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
if (objUploadImg.uploadPicMore && (fileList.length > objUploadImg.onceMaxUpload)) {
objGlobal.DIC.dialog({content:'上传图片一次最多只能选' + objUploadImg.onceMaxUpload + '张', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
if (objUploadImg.uploadPicMore && (fileList.length > (objUploadImg.maxUpload - objUploadImg.countUpload()))) {
objGlobal.DIC.dialog({content:'你最多只能上传' + objUploadImg.maxUpload + '张照片', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
for (var i = 0; i < fileList.length; i++) {
if (objUploadImg.countUpload() >= objUploadImg.maxUpload) {
objGlobal.DIC.dialog({content:'你最多只能上传' + objUploadImg.maxUpload + '张照片', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
break;
}
var file = fileList[i];
if (!objUploadImg.checkPicType(file)) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
continue;
}
// console.log(file);
if (!objUploadImg.checkPicSize(file)) {
objGlobal.DIC.dialog({content:'图片大小超过'+ objUploadImg.uploadPicSize + 'MB', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
continue;
}
var id = Date.now() + i;
// 增加到上传对象中, 上传完成后,修改为 true
objUploadImg.uploadInfo[id] = {
oldFileInfo: file,
file: file,
isDone: false,
};
var html = '<li id="li' + id + '"><div class="mbupload_photoCut"><img src="' + objUploadImg.uploadDefaultImgUrl + '" class="attchImg" alt="photo"></div>' +
'<div class="mbupload_maskLay"></div>' +
'<div class="mbupload_maskTxt">图片压缩中...</div>' +
'<a href="javascript:;" class="mbupload_cBtn mbupload_pa mbupload_db" title="" _id="'+id+'">关闭</a></li>';
$(objUploadImg.formHtmlId + ' .mbupload_addPic').before(html);
objUploadImg.previewQueue.push(id);
// 图片已经上传了 最大限制 张数,隐藏 + 号
if (objUploadImg.countUpload() >= objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').hide();
}
//更新剩余上传数
setTimeout(function(){
objUploadImg.uploadRemaining();
}, 400);
}
// 把输入框清空
$(this).val('');
});
$(objUploadImg.formHtmlId + ' .mbupload_photoList').on('click', '.mbupload_cBtn', function() {
var id = $(this).attr('_id');
// 取消这个请求
if (objUploadImg.xhr[id]) {
objUploadImg.xhr[id].abort();
}
// 图片删除
$(objUploadImg.formHtmlId + ' #li' + id).remove();
// 表单中删除
$(objUploadImg.formHtmlId + ' #input' + id).remove();
objUploadImg.uploadInfo[id] = null;
// 图片变少了,显示+号
if (objUploadImg.countUpload() < objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').show();
}
//更新剩余上传数
objUploadImg.uploadRemaining();
//当删除所有图片后隐藏添加图片的图标
if($(objUploadImg.formHtmlId + ' .mbupload_photoList').find('li').length < 2){
$(objUploadImg.formHtmlId + ' .mbupload_photoList').hide();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').show();
}
});
};
objUploadImg.uploadAddInput();
objUploadImg.uploadRemaining();
initUpload();
};
20160411更新:
使同个页面可以配置调用多个上传图片
20160418更新:
修复上传进度条不准
增加上传样式2,调整部分样式
一些配置问题:
objUploadImg.uploadMaxW = 2000; //生成图片的最大宽度
objUploadImg.uploadMaxH = 2000; //生成图片的最大高度
*建议这两项默认800800
objUploadImg.uploadPicMore = true;//是否允许多图上传 默认单张上传
即便开启,安卓也只支持单张上传
objUploadImg.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
最好不要过多,因为图片在前端用H5 <canvas> 处理,测试过配置最大宽高为2000px时,iPhone6微信端一次上传20张会出现微信自动关闭;如果同个页面调用多个上传方法,一次上传的最大张数之和最好不超过10张**
其他的自行查看附件demo,随便贴几段代码,注意JS代码的引用位置
<!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" href="css/mobile-uploadImg.css">
<script src="js/jquery-1.9.0.js"></script>
<script src="js/mobile-uploadCompresserImg.js"></script>
<script src="js/mobile-uploadImg.js"></script>
</head>
<body style="background: #f5f5f5;">
<div style="margin:20px 10px;">
<form method="post" action="">
<div id="uploadImgForm">
<div class="mbupload_frame">
<div class="mbupload_photoList">
<ul>
<li class="mbupload_on mbupload_addPic mbupload_addImg"></li>
</ul>
<p class="mbupload_textTip mbupload_f12">还可上传<span class="mbupload_onlyUploadNum"></span>张照片呦~</p>
</div>
<div class="mbupload_bgimg">
<div class="iconSendImg mbupload_addImg" style="background:url(images/upload_carbg.png) no-repeat 50% 50%;"></div>
</div>
</div>
</div>
<div style="margin-top:20px;">
<div id="uploadImgForm2" class="uploadImgStyle2">
<div class="mbupload_frame">
<div class="mbupload_photoList">
<ul>
<li class="mbupload_on mbupload_addPic mbupload_addImg"></li>
</ul>
<p class="mbupload_textTip mbupload_f12">还可上传<span class="mbupload_onlyUploadNum"></span>张照片呦~</p>
</div>
<div class="mbupload_bgimg">
<div class="iconSendImg mbupload_addImg" style="background:url(images/upload_licensebg.png) no-repeat 50% 50%;"></div>
</div>
</div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
var objUploadImgForm = {};
objUploadImgForm.uploadUrl = "<?php echo('http://'.$_SERVER['HTTP_HOST'].'/uploads.php') ?>";//上传图片的地址
objUploadImgForm.formHtmlId = "#uploadImgForm";//上传图片的ID
objUploadImgForm.maxUpload = 20;//上传图片的最大张数
objUploadImgForm.uploadMaxW = 2000; //生成图片的最大宽度
objUploadImgForm.uploadMaxH = 2000; //生成图片的最大高度
objUploadImgForm.uploadQuality = 1; //目标jpg图片输出质量
objUploadImgForm.uploadPicSize = 8;//上传限制图片大小(MB) 默认8M
objUploadImgForm.uploadPicMore = true;//是否允许多图上传 默认单张上传
objUploadImgForm.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
objUploadImgForm.uploadDefaultImgUrl = "images/defaultImg.png";//压缩图片时的默认图片地址
mobileUploadImg(objUploadImgForm);
</script>
<script type="text/javascript">
var objUploadImgForm2 = {};
objUploadImgForm2.uploadUrl = "<?php echo('http://'.$_SERVER['HTTP_HOST'].'/uploads.php') ?>";//上传图片的地址
objUploadImgForm2.formHtmlId = "#uploadImgForm2";//上传图片的ID
objUploadImgForm2.maxUpload = 1;//上传图片的最大张数
objUploadImgForm2.uploadMaxW = 800; //生成图片的最大宽度
objUploadImgForm2.uploadMaxH = 800; //生成图片的最大高度
objUploadImgForm2.uploadQuality = 1; //目标jpg图片输出质量
objUploadImgForm2.uploadPicSize = 8;//上传限制图片大小(MB) 默认8M
objUploadImgForm2.uploadPicMore = true;//是否允许多图上传 默认单张上传
objUploadImgForm2.onceMaxUpload = 10;//多图上传时,一次上传的最大张数 默认10
objUploadImgForm2.uploadDefaultImgUrl = "images/defaultImg.png";//压缩图片时的默认图片地址
mobileUploadImg(objUploadImgForm2);
</script>
</body>
</html>
/**
* @filename mobile-uploadImg
* @description
* 作者: 418239385(418239385@qq.com)
* 创建时间: 2016-4-6 14:38:03
* 修改记录:
*
**/
//------------------------------------------------------------------------------
function mobileUploadImg(opts)
{
if(opts == null){
objGlobal.DIC.dialog({content:'请配置上传图片的相关参数!', autoClose:false, okValue:"确定", isMask:true});
return;
}
var objUploadImg = {};
var opts = opts || {};
//上传图片的表单ID
objUploadImg.formHtmlId = opts.formHtmlId || "";
//最大上传图片量
objUploadImg.maxUpload = opts.maxUpload || 8;
//生成图片的最大宽度
objUploadImg.uploadMaxW = opts.uploadMaxW || 800;
//生成图片的最大高度
objUploadImg.uploadMaxH = opts.uploadMaxH || 800;
//目标jpg图片输出质量
objUploadImg.uploadQuality = opts.uploadQuality || 1;
//上传限制图片体积(MB) 默认8M
objUploadImg.uploadPicSize = opts.uploadPicSize || 8;
//是否允许多图上传 默认单张上传
objUploadImg.uploadPicMore = opts.uploadPicMore || false;
//多图上传时,一次上传的最大张数 默认10
objUploadImg.onceMaxUpload = opts.onceMaxUpload || 10;
// 上传图片地址
objUploadImg.uploadUrl = opts.uploadUrl || "";
//压缩图片时的默认图片地址
objUploadImg.uploadDefaultImgUrl = opts.uploadDefaultImgUrl || "";
//多图上传时,上传第一张到最后一张的状态
objUploadImg.isMoreBusy = false;
// 上传信息 主要是 id 对应信息
objUploadImg.uploadInfo = {};
// 上传队列,里面保存的是 id
objUploadImg.uploadQueue = [];
// 预览队列,里面保存的是 id
objUploadImg.previewQueue = [];
// 请求对象
objUploadImg.xhr = {};
// 是否有图片正在压缩
objUploadImg.isEncoderBusy = false;
// 是否有任务正在上传
objUploadImg.isBusy = false;
if(objUploadImg.formHtmlId.length <= 0){
objGlobal.DIC.dialog({content:'请配置上传图片的容器ID!', autoClose:false, okValue:"确定", isMask:true});
return;
}
if(objUploadImg.uploadUrl.length <= 0){
objGlobal.DIC.dialog({content:'请配置上传图片的URL地址!', autoClose:false, okValue:"确定", isMask:true});
return;
}
objUploadImg.countUpload = function() {
var num = 0;
$.each(objUploadImg.uploadInfo, function(i, n) {
if (n) {
++ num;
}
});
return num;
};
// 图片预览
objUploadImg.uploadPreview = function(id) {
var reader = new FileReader();
var uploadBase64;
var conf = {}, file = objUploadImg.uploadInfo[id].file;
conf = {
maxW: objUploadImg.uploadMaxW, //目标宽
maxH: objUploadImg.uploadMaxH, //目标高
quality: objUploadImg.uploadQuality, //目标jpg图片输出质量
};
reader.onload = function(e) {
var result = this.result;
// 如果是jpg格式图片,读取图片拍摄方向,自动旋转
if (file.type == 'image/jpeg'){
try {
var jpg = new objJpegMeata.JpegMeta.JpegFile(result, file.name);
} catch (e) {
objGlobal.DIC.dialog({content:'图片不是正确的图片数据', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
if (jpg.tiff && jpg.tiff.Orientation) {
//设置旋转
conf = $.extend(conf, {
orien: jpg.tiff.Orientation.value
});
}
}
// 压缩
if (objImageCompresser.ImageCompresser.support()) {
var img = new Image();
img.onload = function() {
try {
uploadBase64 = objImageCompresser.ImageCompresser.getImageBase64(this, conf);
} catch (e) {
objGlobal.DIC.dialog({content:'压缩图片失败', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
if (uploadBase64.indexOf('data:image') < 0) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
objUploadImg.uploadInfo[id].file = uploadBase64;
$(objUploadImg.formHtmlId + ' #li' + id).find('img').attr('src', uploadBase64);
objUploadImg.uploadQueue.push(id);
}
img.onerror = function() {
objGlobal.DIC.dialog({content:'解析图片数据失败', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
img.src = objImageCompresser.ImageCompresser.getFileObjectURL(file);
} else {
uploadBase64 = result;
if (uploadBase64.indexOf('data:image') < 0) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
$(objUploadImg.formHtmlId + ' #li' + id).remove();
objUploadImg.isEncoderBusy = false;
return false;
}
objUploadImg.uploadInfo[id].file = uploadBase64;
$(objUploadImg.formHtmlId + ' #li' + id).find('img').attr('src', uploadBase64);
objUploadImg.uploadQueue.push(id);
}
}
reader.readAsBinaryString(objUploadImg.uploadInfo[id].file);
};
// 创建上传请求
objUploadImg.createUpload = function(id, type, uploadTimer) {
if (!objUploadImg.uploadInfo[id]) {
objUploadImg.isEncoderBusy = false;
objUploadImg.isBusy = false;
return false;
}
// 移除图片压缩中...
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskTxt').remove();
// 图片posturl
var uploadUrl = objUploadImg.uploadUrl;
// 产生进度条
var progressHtml = '<div class="mbupload_progress mbupload_brSmall" id="mbupload_progress'+id+'"><div class="mbupload_proBar" style="width:0%;"></div></div>';
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskLay').after(progressHtml);
var formData = new FormData();
formData.append('upload_pic', objUploadImg.uploadInfo[id].file);
formData.append('upload_name', objUploadImg.uploadInfo[id].oldFileInfo.name);
formData.append('upload_id', id);
var progress = function(e) {
if (e.target.response) {
var result = $.parseJSON(e.target.response);
if (result.errCode != 0) {
// $('#content').val(result.errCode);
objGlobal.DIC.dialog({content:'网络不稳定,请稍后重新操作', autoClose:true});
removePic(id);
//更新剩余上传数
objUploadImg.uploadRemaining();
return false;
}
}
var progress = $(objUploadImg.formHtmlId + ' #mbupload_progress' + id).find('.mbupload_proBar');
if (e.total == e.loaded) {
var percent = 100;
} else {
var percent = 100*(e.loaded / e.total);
}
// 控制进度条不要超出
if (percent > 100) {
percent = 100;
}
progress.width(percent + '%');
//progress.animate({'width': '95%'}, 1500);
setTimeout(function(){
if (percent == 100) {
donePic(id);
var pLength = 0, nLength = 0;
if(objUploadImg.uploadPicMore){
pLength = objUploadImg.previewQueue.length;
nLength = objUploadImg.uploadQueue.length;
}
if(uploadTimer && pLength <= 0 && nLength <= 0){
clearInterval(uploadTimer);
}
}
}, 400);
}
var removePic = function(id) {
donePic(id);
$('#li' + id).remove();
}
var donePic = function(id) {
objUploadImg.isEncoderBusy = false;
objUploadImg.isBusy = false;
if(objUploadImg.uploadPicMore && (objUploadImg.previewQueue.length <= 0) &&
(objUploadImg.uploadQueue.length <= 0)){
objUploadImg.isMoreBusy = false;
}
if (typeof objUploadImg.uploadInfo[id] != 'undefined') {
objUploadImg.uploadInfo[id].isDone = true;
}
if (typeof objUploadImg.xhr[id] != 'undefined') {
objUploadImg.xhr[id] = null;
}
}
var complete = function(e) {
var progress = $(objUploadImg.formHtmlId + ' #mbupload_progress' + id).find('.mbupload_proBar');
progress.css('width', '100%');
if($(objUploadImg.formHtmlId + ' #li' + id)){
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskTxt').remove();
}
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_maskLay').remove();
$(objUploadImg.formHtmlId + ' #li' + id).find('.mbupload_progress').remove();
// 上传结束
donePic(id);
var result = $.parseJSON(e.target.response);
if (result.errCode == 0) {
var input = '<input type="hidden" id="input' + result.data.id + '" name="picIds[]" value="' + result.data.picId + '">';
if(type == 'replyForm'){
$('#replyForm').append(input);
}else{
$(objUploadImg.formHtmlId).append(input);
}
} else {
objGlobal.DIC.dialog({content:'网络不稳定,请稍后重新操作', autoClose:true});
removePic(id);
//更新剩余上传数
objUploadImg.uploadRemaining();
delete objUploadImg.uploadInfo[id];
// 如果传略失败,上传个数少于限制张数则再显示加号
if (objUploadImg.countUpload() < objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').show();
}
}
}
var failed = function() {
objGlobal.DIC.dialog({content:'网络断开,请稍后重新操作', autoClose:true});
removePic(id)
}
var abort = function() {
objGlobal.DIC.dialog({content:'上传已取消', autoClose:true});
removePic(id)
}
// 创建 ajax 请求
objUploadImg.xhr[id] = new XMLHttpRequest();
objUploadImg.xhr[id].addEventListener("progress", progress, false);
objUploadImg.xhr[id].upload.addEventListener("progress", progress, false);
objUploadImg.xhr[id].addEventListener("load", complete, false);
objUploadImg.xhr[id].addEventListener("abort", abort, false);
objUploadImg.xhr[id].addEventListener("error", failed, false);
objUploadImg.xhr[id].open("POST", uploadUrl);
objUploadImg.xhr[id].send(formData);
};
// 不能上传系统提示
objUploadImg.checkUploadBySysVer = function() {
var mb_os = objGlobal.checkUA();
if (mb_os.ios && mb_os.version.toString() < '6.0') {
objGlobal.DIC.dialog({content:'手机系统不支持传图,请升级到ios6.0以上', autoClose:true});
return false;
}
if (mb_os.wx && mb_os.wxVersion.toString() < '5.2') {
objGlobal.DIC.dialog({content:'当前微信版本不支持传图,请升级到最新版', autoClose:true});
return false;
}
return true;
};
//根据是否可以多图上传生成对应的input
objUploadImg.uploadAddInput = function(){
var input = "", fistInput = "";
if(objUploadImg.uploadPicMore){
input = '<input type="file" class="mbupload_on mbupload_uploadFile" accept="image/*" multiple="">';
fistInput = '<input type="file" class="fistUpload" accept="image/*" multiple="">';
}else{
input = '<input type="file" class="mbupload_on mbupload_uploadFile" accept="image/*" single="">';
fistInput = '<input type="file" class="fistUpload" accept="image/*" single="">';
}
$(objUploadImg.formHtmlId + ' .mbupload_addPic').append(input);
$(objUploadImg.formHtmlId + ' .iconSendImg').append(fistInput);
};
//剩余上传数
objUploadImg.uploadRemaining = function(){
var uploadNum = 0;
uploadNum = $(objUploadImg.formHtmlId + ' .mbupload_photoList').find('li').length;
var canOnlyUploadNum = objUploadImg.maxUpload;
if(uploadNum <= objUploadImg.maxUpload)
{
canOnlyUploadNum = objUploadImg.maxUpload - uploadNum + 1;
}
else
{
canOnlyUploadNum = 0;
}
//当上传出错则显示第一上传页面
if(canOnlyUploadNum == objUploadImg.maxUpload)
{
$(objUploadImg.formHtmlId + ' .mbupload_photoList').hide();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').show();
}
//更新剩余可上传图片数
$(objUploadImg.formHtmlId + ' .mbupload_onlyUploadNum').html(canOnlyUploadNum);
};
// 检查图片大小
objUploadImg.checkPicSize = function(file) {
var uploadPicSize = objUploadImg.uploadPicSize*1024*1024;
if (file.size > uploadPicSize) {
return false;
}
return true;
};
// 检查图片类型
objUploadImg.checkPicType = function(file) {
var photoReg = (/\.png$|\.bmp$|\.jpg$|\.jpeg$|\.gif$/i);
if(!photoReg.test(file.name)){
return false;
}else{
return true;
}
};
var uploadTimer = null;
var initUpload = function()
{
// 上传图片的绑定
$(objUploadImg.formHtmlId + ' .mbupload_addImg').on("click", function(){
if(!objUploadImg.checkUploadBySysVer()){
return false;
}
});
$(objUploadImg.formHtmlId + ' .mbupload_uploadFile').on("click", function(){
var thisObj = $(this);
if (objUploadImg.isEncoderBusy) {
return false;
}
else if (objUploadImg.isBusy) {
objGlobal.DIC.dialog({content:'上传中,请稍后添加', autoClose:true});
return false;
}
else if (objUploadImg.isMoreBusy) {
objGlobal.DIC.dialog({content:'上传中,请稍后添加', autoClose:true});
return false;
}
});
//首次点击图片的图标,触发一次手机的默认上传事件
$('body').on('change', objUploadImg.formHtmlId + ' .fistUpload', function(e){
$(objUploadImg.formHtmlId + ' .mbupload_photoList').show();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').hide();
});
// 文件表单发生变化时
$('body').on('change', objUploadImg.formHtmlId + ' .mbupload_uploadFile,' + objUploadImg.formHtmlId + ' .fistUpload', function(e) {
//执行图片预览、压缩定时器
uploadTimer = setInterval(function() {
// 预览
setTimeout(function() {
if (!objUploadImg.isEncoderBusy && objUploadImg.previewQueue.length) {
var jobId = objUploadImg.previewQueue.shift();
objUploadImg.isEncoderBusy = true;
objUploadImg.uploadPreview(jobId);
}
}, 1);
// 上传
setTimeout(function() {
if (!objUploadImg.isBusy && objUploadImg.uploadQueue.length) {
var jobId = objUploadImg.uploadQueue.shift();
objUploadImg.isBusy = true;
if(objUploadImg.uploadPicMore){
objUploadImg.isMoreBusy = true;
}
objUploadImg.createUpload(jobId, objUploadImg.formHtmlId, uploadTimer);
}
}, 10);
}, 300);
e = e || window.event;
var fileList = e.target.files;
if (!fileList.length) {
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
if (objUploadImg.uploadPicMore && (fileList.length > objUploadImg.onceMaxUpload)) {
objGlobal.DIC.dialog({content:'上传图片一次最多只能选' + objUploadImg.onceMaxUpload + '张', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
if (objUploadImg.uploadPicMore && (fileList.length > (objUploadImg.maxUpload - objUploadImg.countUpload()))) {
objGlobal.DIC.dialog({content:'你最多只能上传' + objUploadImg.maxUpload + '张照片', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
return false;
}
for (var i = 0; i < fileList.length; i++) {
if (objUploadImg.countUpload() >= objUploadImg.maxUpload) {
objGlobal.DIC.dialog({content:'你最多只能上传' + objUploadImg.maxUpload + '张照片', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
break;
}
var file = fileList[i];
if (!objUploadImg.checkPicType(file)) {
objGlobal.DIC.dialog({content:'上传照片格式不支持', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
continue;
}
// console.log(file);
if (!objUploadImg.checkPicSize(file)) {
objGlobal.DIC.dialog({content:'图片大小超过'+ objUploadImg.uploadPicSize + 'MB', autoClose:true});
//更新剩余上传数
objUploadImg.uploadRemaining();
$(this).val('');
continue;
}
var id = Date.now() + i;
// 增加到上传对象中, 上传完成后,修改为 true
objUploadImg.uploadInfo[id] = {
oldFileInfo: file,
file: file,
isDone: false,
};
var html = '<li id="li' + id + '"><div class="mbupload_photoCut"><img src="' + objUploadImg.uploadDefaultImgUrl + '" class="attchImg" alt="photo"></div>' +
'<div class="mbupload_maskLay"></div>' +
'<div class="mbupload_maskTxt">图片压缩中...</div>' +
'<a href="javascript:;" class="mbupload_cBtn mbupload_pa mbupload_db" title="" _id="'+id+'">关闭</a></li>';
$(objUploadImg.formHtmlId + ' .mbupload_addPic').before(html);
objUploadImg.previewQueue.push(id);
// 图片已经上传了 最大限制 张数,隐藏 + 号
if (objUploadImg.countUpload() >= objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').hide();
}
//更新剩余上传数
setTimeout(function(){
objUploadImg.uploadRemaining();
}, 400);
}
// 把输入框清空
$(this).val('');
});
$(objUploadImg.formHtmlId + ' .mbupload_photoList').on('click', '.mbupload_cBtn', function() {
var id = $(this).attr('_id');
// 取消这个请求
if (objUploadImg.xhr[id]) {
objUploadImg.xhr[id].abort();
}
// 图片删除
$(objUploadImg.formHtmlId + ' #li' + id).remove();
// 表单中删除
$(objUploadImg.formHtmlId + ' #input' + id).remove();
objUploadImg.uploadInfo[id] = null;
// 图片变少了,显示+号
if (objUploadImg.countUpload() < objUploadImg.maxUpload) {
$(objUploadImg.formHtmlId + ' .mbupload_addPic').show();
}
//更新剩余上传数
objUploadImg.uploadRemaining();
//当删除所有图片后隐藏添加图片的图标
if($(objUploadImg.formHtmlId + ' .mbupload_photoList').find('li').length < 2){
$(objUploadImg.formHtmlId + ' .mbupload_photoList').hide();
$(objUploadImg.formHtmlId + ' .mbupload_bgimg').show();
}
});
};
objUploadImg.uploadAddInput();
objUploadImg.uploadRemaining();
initUpload();
};
收起阅读 »

iOS键盘弹出后PopPicker出现的临时解决方法
原因:和iOS中其他有input的地方出现错乱的情况一样,poppicker的样式使用了fixed:
.mui-poppicker {
position: fixed;
}
在mui.poppicker.css中。
所以,分别在poppicker的显示和隐藏代码中对poppicker的display做处理。这里的显示和隐藏其实是修改poppicker的样式bottom,分别是0px和-300px,配合了动画的css,并没有改变display,所以,键盘弹出时poppicker露了出来。
解决方法:
mui.poppicker.js中增加初始化、show和hide方法中display的改变。
```javascript
//init构造函数最后增加两行:
self.panel.style.display = 'none';
self.body.style.display = 'none';
//显示
show: function(callback) {
var self = this;
//增加以下2行
self.panel.style.display = 'block';
self.body.style.display = 'block';
self.callback = callback;
self.mask.show();
document.body.classList.add($.className('poppicker-active-for-page'));
self.panel.classList.add($.className('active'));
//处理物理返回键
self.__back = $.back;
$.back = function() {
self.hide();
};
},
//隐藏
hide: function() {
var self = this;
if (self.disposed) return;
self.panel.classList.remove($.className('active'));
self.mask.close();
document.body.classList.remove($.className('poppicker-active-for-page'));
//增加以下2行
self.panel.style.display = 'none';
self.body.style.display = 'none';
//处理物理返回键
$.back=self.__back;
}
原因:和iOS中其他有input的地方出现错乱的情况一样,poppicker的样式使用了fixed:
.mui-poppicker {
position: fixed;
}
在mui.poppicker.css中。
所以,分别在poppicker的显示和隐藏代码中对poppicker的display做处理。这里的显示和隐藏其实是修改poppicker的样式bottom,分别是0px和-300px,配合了动画的css,并没有改变display,所以,键盘弹出时poppicker露了出来。
解决方法:
mui.poppicker.js中增加初始化、show和hide方法中display的改变。
```javascript
//init构造函数最后增加两行:
self.panel.style.display = 'none';
self.body.style.display = 'none';
//显示
show: function(callback) {
var self = this;
//增加以下2行
self.panel.style.display = 'block';
self.body.style.display = 'block';
self.callback = callback;
self.mask.show();
document.body.classList.add($.className('poppicker-active-for-page'));
self.panel.classList.add($.className('active'));
//处理物理返回键
self.__back = $.back;
$.back = function() {
self.hide();
};
},
//隐藏
hide: function() {
var self = this;
if (self.disposed) return;
self.panel.classList.remove($.className('active'));
self.mask.close();
document.body.classList.remove($.className('poppicker-active-for-page'));
//增加以下2行
self.panel.style.display = 'none';
self.body.style.display = 'none';
//处理物理返回键
$.back=self.__back;
}
收起阅读 »

上拉加载的坑爹联想!
用Hbuild编辑器做上啦加载,被坑爹的联想害了一整天,无力吐槽,endPullupToRefresh(),就这个关闭方法,操,联想出来的是这样的endPullUpToRefresh,看哪个up,联想出来的是大写的,我就无语了,又遇到相同情况的注意一下!!!
用Hbuild编辑器做上啦加载,被坑爹的联想害了一整天,无力吐槽,endPullupToRefresh(),就这个关闭方法,操,联想出来的是这样的endPullUpToRefresh,看哪个up,联想出来的是大写的,我就无语了,又遇到相同情况的注意一下!!!

[源码分享]wordpress转APP玩具
Wordpress-Mobile-Application
利用wordpress
作为后台,构建App
源码地址:github
用到的技术
html5+:http://www.dcloud.io/docs/api/
mui: http://dcloudio.github.io/mui/
hbuilder:[http://www.dcloud.io] (http://www.dcloud.io/)
构建方法
- 安装
wordpress
- 为
wordpress
安装wordpress rest api
(2.0版本及以上) - 在
wordpress
后台:设置/固定链接设置为文章格式 - 更改
/js/app.js
里面的name
和菜单名称和对应的id
(可在example.com/wp-json/wp/v2/categories
查看) 下载hbuilde
,选择文件/打开目录(打开本项目代码目录),双击manifest.json
设置app
名称和id
,修改app
图标和启动图。- 点击发行,发行为原生应用,设置好开发者证书,然后打包。
打包成功后会自动下载到本地目录,这样一个App
就制作好了。
项目截图
License
The MIT License (MIT)
Copyright (c) 2016 Zhen.Wang
Wordpress-Mobile-Application
利用wordpress
作为后台,构建App
源码地址:github
用到的技术
html5+:http://www.dcloud.io/docs/api/
mui: http://dcloudio.github.io/mui/
hbuilder:[http://www.dcloud.io] (http://www.dcloud.io/)
构建方法
- 安装
wordpress
- 为
wordpress
安装wordpress rest api
(2.0版本及以上) - 在
wordpress
后台:设置/固定链接设置为文章格式 - 更改
/js/app.js
里面的name
和菜单名称和对应的id
(可在example.com/wp-json/wp/v2/categories
查看) 下载hbuilde
,选择文件/打开目录(打开本项目代码目录),双击manifest.json
设置app
名称和id
,修改app
图标和启动图。- 点击发行,发行为原生应用,设置好开发者证书,然后打包。
打包成功后会自动下载到本地目录,这样一个App
就制作好了。
项目截图
License
The MIT License (MIT)
Copyright (c) 2016 Zhen.Wang
收起阅读 »