HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

3年前端开发经验,用mui实战做过APP,现 找工作!求带走!

求职 招聘

性别:男
三年前端开发经验
由于现在公司经营不善,一不小心技术部解散,无奈,只好拂袖而去,现在待业在家,哪位老板愿带我回家,定不负所托,完成任务。

本人近况:之前公司是一家电商公司,当初去公司的时候我负责的就是整个前端开发组的小组长,带领2人完成整套APP的开发,现在已经全部开发完成,安卓市场,IOS商店均可下载,(由于自我保护,恕在下不能公布APP名称,想要招人的可以联系我QQ 245132346 )。
目前有公司想用mui 开发APP的公司 你要了我 等于要了一套APP代码,这都是小 关键本人 已熟练掌握 mui H5+核心要素 包括其调用手机底层功能 支付宝支付,微信支付等等。

本人目前所掌握的技能:require react webpack vue swiper less JQ zepto ...

去年我一直做的 手机站的 网页 对于移动端网页开发 有着深刻的理解 再加上一段APP开发的经历 更是深入我心,自认为 去任何一家公司 无需学习 无需培养 老夫衣袖一挥 对着电脑就是干。(语言颇有不妥 懂我者自懂 如果您的公司 是一家只知道工作 无一点自由 幽默 谈笑的空间 那对不起 请勿打扰)

有意向的公司 加QQ要我的简历 期待与您的合作。 245132346

继续阅读 »

性别:男
三年前端开发经验
由于现在公司经营不善,一不小心技术部解散,无奈,只好拂袖而去,现在待业在家,哪位老板愿带我回家,定不负所托,完成任务。

本人近况:之前公司是一家电商公司,当初去公司的时候我负责的就是整个前端开发组的小组长,带领2人完成整套APP的开发,现在已经全部开发完成,安卓市场,IOS商店均可下载,(由于自我保护,恕在下不能公布APP名称,想要招人的可以联系我QQ 245132346 )。
目前有公司想用mui 开发APP的公司 你要了我 等于要了一套APP代码,这都是小 关键本人 已熟练掌握 mui H5+核心要素 包括其调用手机底层功能 支付宝支付,微信支付等等。

本人目前所掌握的技能:require react webpack vue swiper less JQ zepto ...

去年我一直做的 手机站的 网页 对于移动端网页开发 有着深刻的理解 再加上一段APP开发的经历 更是深入我心,自认为 去任何一家公司 无需学习 无需培养 老夫衣袖一挥 对着电脑就是干。(语言颇有不妥 懂我者自懂 如果您的公司 是一家只知道工作 无一点自由 幽默 谈笑的空间 那对不起 请勿打扰)

有意向的公司 加QQ要我的简历 期待与您的合作。 245132346

收起阅读 »

关于.net的webservice的跨域访问

AJAX跨域

现象:在本机模拟器以及浏览器模式,可以正常访问,真机运行或打包成app到真机上都不行。
解决:
主要修改是在webconfig中的配置,除了必须的
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Authorization, Accept,X-Requested-With"/>
</customHeaders>
</httpProtocol>
</system.webServer>

还要配置协议
<webServices>
<protocols>
<add name="HttpSoap" />
<add name="HttpPost" />
<add name="HttpGet" />
</protocols>
</webServices>
奇怪的是,不配置协议时,默认情况只有soap,在模拟器上可以正常跑,到手机上就不行了。

继续阅读 »

现象:在本机模拟器以及浏览器模式,可以正常访问,真机运行或打包成app到真机上都不行。
解决:
主要修改是在webconfig中的配置,除了必须的
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Authorization, Accept,X-Requested-With"/>
</customHeaders>
</httpProtocol>
</system.webServer>

还要配置协议
<webServices>
<protocols>
<add name="HttpSoap" />
<add name="HttpPost" />
<add name="HttpGet" />
</protocols>
</webServices>
奇怪的是,不配置协议时,默认情况只有soap,在模拟器上可以正常跑,到手机上就不行了。

收起阅读 »

使用JavaScriptCore 实现OC与JS的交互

一、说明这篇文章记录自己在研究OC与JS交互中的所得,以及遇到的问题与解决
由于苹果的审核时间太漫长,一次审核不过,那又将进入另一个漫长的审核期。为了能在开发中方便更新,公司要求在项目中使用HTML5,这样就涉及到OC与JS的交互,不懂H5,不懂JS。在经过一段时间的摸索之后,将自己的研究记录下来,以做备忘。
OC与JS的交互实现方式有很多,之前用的比较多的是WebViewJavaScriptBridge,但在IOS7之后,苹果将JavaScriptCore框架开放。因此,这篇文章不讲理论,主要讲的是JavaScriptCore的实际使用。
文中所用的项目JavaScriptCoreDemo
废话说完了,下面进入正题

二、Demo项目中功能介绍

Demo首页
这个demo主要分为了三个部分来:
1.JS Call OC , JS调用OC的函数
2.OC Call JS , OC调用JS的函数
3.一个绘图的例子

在做OC与JS交互工作之前,我们需要做些准备工作
1.导入JavaScriptCore的头文件

import <JavaScriptCore/JavaScriptCore.h>

2.用webView加载HTML文件,这里用的是本地HTML;
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"js call oc";

NSString path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"JSCallOC.html"];
NSURLRequest
request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
[self.webView loadRequest:request];
}

3.在JS交互中,很多事情都是在webView的delegate方法中完成的,通过JSContent创建一个使用JS的环境,所以这里,我们先将self.content在这里面初始化;
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13

  • (void)webViewDidFinishLoad:(UIWebView *)webView
    {
    //初始化content
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

// 打印异常,由于JS的异常信息是不会在OC中被直接打印的,所以我们在这里添加打印异常信息,
self.context.exceptionHandler =
^(JSContext context, JSValue exceptionValue)
{
context.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
};
}

三、实际操作中 JS call OC先来看demo

JS Call OC

这个页面整个都是通过HTML实现的,
1 计算阶乘:在输入框中输入一个数字,然后在OC中计算出结果,最后显示在HTML的页面上;
2 测试log:点击后,在后台打印测试数据;
3 OC原生Alert :点击后,弹出OC的提示框;
4 addSubView:点击后,在OC中添加一个View;
5 push to second ViewController :跳转到下一个界面
总结:以上功能都是在OC获取HTML中按钮的点击事件,在后在OC中实现功能.

??如何获取HTML中的点击事件呢??
在HTML中,为一个元素添加点击时间有两种写法
<input type="button" value="计算阶乘" />或者
<input type="button" value="测试log" />
如果是第一种方法,那么就要用JSExport协议关联native的方法,要在webView的delegate里面添加
// 以 JSExport 协议关联 native 的方法self.content[@"native"] = self;添加完之后,要声明一个继承JSExport的协议,协议中声明供JS使用的OC的方法
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
@protocol TestJSExport <JSExport>
JSExportAs
(calculateForJS /* handleFactorialCalculateWithNumber 作为js方法的别名 /,

  • (void)handleFactorialCalculateWithNumber:(NSNumber *)number
    );
    • (void)pushViewController:(NSString )view title:(NSString )title;

-(void)log:(NSString*)l;

@end

在OC中实现这些方法,这样就完成了!

如果是第二章方法,则只需要通过block的形式关联JavaScript function就可以了
!self.context[@"log"] = ^(NSString *str){NSLog(@"%@", str);};

三、OC调用JS

OC调用JS

在这个例子中,界面的所有View都是OC创建的,点击“交给JS处理计算阶乘”后,将textfild的数据传给JS,JS计算完成后在返回来!
这里面首先要获取JS里面的计算函数,在OC中,所有表示JS中对象,都用JSValue来创建,通过objectForKeyedSubscript方法或者直接使用下标的方法获取JS对象,然后使用callWithArguments方法来执行函数
[Objective-C] 查看源文件 复制代码
?
1
2
3
4
5
// 方法一. JSValue function = [self.context objectForKeyedSubscript:@"factorial"];
// 方法二.
JSValue
function = self.context[@"factorial"];
JSValue *result = [function callWithArguments:@[inputNumber]];
self.showLable.text = [NSString stringWithFormat:@"%@", [result toNumber]];

四、demo之外(慢慢在总结)1.JS注入
2.在OC中为JS创建对象
......

零碎的补充1:对于JS 函数中,参数中有函数的,在OC中用JSValue接收
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
// 比如:JS代码[/font] function myFunc({"text":"这里是文字","callbackFun":function(string){alert'string'}});

//OC代码中在.h的protocol中声明JS要调用的OC方法
//.h protocol中,函数名称要和JS中相同,这里接收的参数为JSValue
JSExportAs
(myFunc,
-(void) myFunc:(JSValue*)value
);

//在.m文件中,实现myFunc方法
-(void) myFunc:(JSValue*)value{

NSString * text = [value valueForProperty:@"text"];//打印"这里是文字"

JSValue * func = [value valueForProperty:@"callbackFun"]; //这里是JS参数中的func;

//调用这个函数
[func callWithArguments:@[@"这里是参数"]];

}

demo 直接下载:
[pan=https://github.com/shaojiankui/JavaScriptCore-Demo/archive/master.zip]|10[/pan]

继续阅读 »

一、说明这篇文章记录自己在研究OC与JS交互中的所得,以及遇到的问题与解决
由于苹果的审核时间太漫长,一次审核不过,那又将进入另一个漫长的审核期。为了能在开发中方便更新,公司要求在项目中使用HTML5,这样就涉及到OC与JS的交互,不懂H5,不懂JS。在经过一段时间的摸索之后,将自己的研究记录下来,以做备忘。
OC与JS的交互实现方式有很多,之前用的比较多的是WebViewJavaScriptBridge,但在IOS7之后,苹果将JavaScriptCore框架开放。因此,这篇文章不讲理论,主要讲的是JavaScriptCore的实际使用。
文中所用的项目JavaScriptCoreDemo
废话说完了,下面进入正题

二、Demo项目中功能介绍

Demo首页
这个demo主要分为了三个部分来:
1.JS Call OC , JS调用OC的函数
2.OC Call JS , OC调用JS的函数
3.一个绘图的例子

在做OC与JS交互工作之前,我们需要做些准备工作
1.导入JavaScriptCore的头文件

import <JavaScriptCore/JavaScriptCore.h>

2.用webView加载HTML文件,这里用的是本地HTML;
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"js call oc";

NSString path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"JSCallOC.html"];
NSURLRequest
request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
[self.webView loadRequest:request];
}

3.在JS交互中,很多事情都是在webView的delegate方法中完成的,通过JSContent创建一个使用JS的环境,所以这里,我们先将self.content在这里面初始化;
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13

  • (void)webViewDidFinishLoad:(UIWebView *)webView
    {
    //初始化content
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

// 打印异常,由于JS的异常信息是不会在OC中被直接打印的,所以我们在这里添加打印异常信息,
self.context.exceptionHandler =
^(JSContext context, JSValue exceptionValue)
{
context.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
};
}

三、实际操作中 JS call OC先来看demo

JS Call OC

这个页面整个都是通过HTML实现的,
1 计算阶乘:在输入框中输入一个数字,然后在OC中计算出结果,最后显示在HTML的页面上;
2 测试log:点击后,在后台打印测试数据;
3 OC原生Alert :点击后,弹出OC的提示框;
4 addSubView:点击后,在OC中添加一个View;
5 push to second ViewController :跳转到下一个界面
总结:以上功能都是在OC获取HTML中按钮的点击事件,在后在OC中实现功能.

??如何获取HTML中的点击事件呢??
在HTML中,为一个元素添加点击时间有两种写法
<input type="button" value="计算阶乘" />或者
<input type="button" value="测试log" />
如果是第一种方法,那么就要用JSExport协议关联native的方法,要在webView的delegate里面添加
// 以 JSExport 协议关联 native 的方法self.content[@"native"] = self;添加完之后,要声明一个继承JSExport的协议,协议中声明供JS使用的OC的方法
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
@protocol TestJSExport <JSExport>
JSExportAs
(calculateForJS /* handleFactorialCalculateWithNumber 作为js方法的别名 /,

  • (void)handleFactorialCalculateWithNumber:(NSNumber *)number
    );
    • (void)pushViewController:(NSString )view title:(NSString )title;

-(void)log:(NSString*)l;

@end

在OC中实现这些方法,这样就完成了!

如果是第二章方法,则只需要通过block的形式关联JavaScript function就可以了
!self.context[@"log"] = ^(NSString *str){NSLog(@"%@", str);};

三、OC调用JS

OC调用JS

在这个例子中,界面的所有View都是OC创建的,点击“交给JS处理计算阶乘”后,将textfild的数据传给JS,JS计算完成后在返回来!
这里面首先要获取JS里面的计算函数,在OC中,所有表示JS中对象,都用JSValue来创建,通过objectForKeyedSubscript方法或者直接使用下标的方法获取JS对象,然后使用callWithArguments方法来执行函数
[Objective-C] 查看源文件 复制代码
?
1
2
3
4
5
// 方法一. JSValue function = [self.context objectForKeyedSubscript:@"factorial"];
// 方法二.
JSValue
function = self.context[@"factorial"];
JSValue *result = [function callWithArguments:@[inputNumber]];
self.showLable.text = [NSString stringWithFormat:@"%@", [result toNumber]];

四、demo之外(慢慢在总结)1.JS注入
2.在OC中为JS创建对象
......

零碎的补充1:对于JS 函数中,参数中有函数的,在OC中用JSValue接收
[Objective-C] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
// 比如:JS代码[/font] function myFunc({"text":"这里是文字","callbackFun":function(string){alert'string'}});

//OC代码中在.h的protocol中声明JS要调用的OC方法
//.h protocol中,函数名称要和JS中相同,这里接收的参数为JSValue
JSExportAs
(myFunc,
-(void) myFunc:(JSValue*)value
);

//在.m文件中,实现myFunc方法
-(void) myFunc:(JSValue*)value{

NSString * text = [value valueForProperty:@"text"];//打印"这里是文字"

JSValue * func = [value valueForProperty:@"callbackFun"]; //这里是JS参数中的func;

//调用这个函数
[func callWithArguments:@[@"这里是参数"]];

}

demo 直接下载:
[pan=https://github.com/shaojiankui/JavaScriptCore-Demo/archive/master.zip]|10[/pan]

收起阅读 »

个推 解决Android应用后台运行无法接受推送的问题。

Android 消息推送 个推

【问题描述】

这个问题只在Andoid上出现,因为iOS端使用APNS,所以推送都能及时送达。

在使用个推推送时,一旦用户把应用切换到后台,那么推送的时候就会显示 success_offline 也就是 cilentID离线

而实际上,应用这时候还没有被系统杀死,但是再也无法接受到推送的消息。哪怕重新点开APP,也不会接受到消息,不管是之前的消息,还是从此之后推送的消息。

【解决方案】

首先,保证APP后台的进程没有被杀死。个推官方给出了各个系统的设置 点击这里查看

强烈大家先去读一读 蜡笔小鑫的《推送使用中的各种坑》 @蜡笔小鑫

  • 简单版

    如果不要求后台还能接收实时推送,只是想在用户重新点开APP时能够接受到之前的消息,并且让用户能够继续接收推送。那么只需要在APP切换到前台的时候,重新初始化个推sdk。

    代码如下:

    /**  
    * resume 应用从后台切换到前台的事件  
    */  
    document.addEventListener("resume", function() {  
    var pushManager = plus.android.importClass("com.igexin.sdk.PushManager");  
    var context = plus.android.runtimeMainActivity();  
    pushManager.getInstance().initialize(context);  
    }, false);
  • 复杂版

    如果想要后台还能实时接收推送,那么只能进行离线打包,修改项目的 AndroidManifest.xml 文件。

    增加一行代码,如下:

    <!-- 整段位置在225行左右 -->  
    <activity  
           android:name="io.dcloud.PandoraEntryActivity"  
           android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"  
           android:hardwareAccelerated="true"  
           android:label="5+Debug"  
           android:launchMode="singleTask"  
           android:screenOrientation="user"  
           android:process=":pushservice" <!-- 这一行就是增加的代码 -->  
           android:theme="@style/DCloudTheme"  
           android:windowSoftInputMode="adjustResize" >  
       </activity>

【解决过程】

原本以为是以为个推的SDK版本问题。5+SDK集成的个推版本是2.7.0.0,而现在官方发布的版本是2.9.3.0。但是把个推官方的SDK下载编译之后,后台仍然不能接受消息。

我用的开发机是小米5,在“更多应用”中检查的时候,发现当应用后台化的时候,“运行中”的应用列表中会显出APP的名字,显示“1个进程和0个服务”。 然后大概五秒钟后,应用就会从“运行中”列表消失,出现在“已缓存”的列表中。

但是个推的SDK是有一个后台服务的,名字叫做 NoticationCenter, 用来管理推送消息。也就是说,我们的应用没有成功唤起 NoticationCenter 这个服务。

但是鄙人只是了解过安卓开发的一点点知识 (web全栈就已经够费精力了好嘛~ 老板加工资好嘛~) ,只能尝试使用 Native.js 拉起个推的 PushService ,然并卵,失败了。

拉起服务的代码是这样的 :

  var main = plus.android.runtimeMainActivity();  
  var Intent = plus.android.importClass('android.content.Intent');  
  var intent = new Intent();  
  var serviceName = 'com.igexin.sdk.PushService';//把这里换成其他Service的名字,也可以实现拉取自定义的Service  
  intent.setClassName(main, serviceName);  
  main.startService(intent);

注 : 把serviceName换成 'com.igexin.sdk.PushServiceForUser', 能够拉起一个NoticationCenterForUser服务,原本以为是和PushService一样的,结果发现这个服务对于推送啥一点用都没有……

然后又进行对比,发现个推的官方Demo里,在 AndroidManifest.xml 里,对于SDK的两个activity又些许的差别。

第一部分:

 <!-- 第三方应用配置 -->  
 <activity  
     android:name=".GetuiSdkDemoActivity"  
     android:label="@string/app_name"  
     android:launchMode="singleTop" >  
     <intent-filter>  
         <action android:name="android.intent.action.MAIN" />  

         <category android:name="android.intent.category.LAUNCHER" />  
     </intent-filter>  
 </activity>

第二部分

<activity  
     android:name="com.igexin.sdk.GActivity"  
     android:excludeFromRecents="true"  
     android:exported="true"  
     android:process=":pushservice"  <!--就是这里,process属性-->  
     android:taskAffinity="com.igexin.sdk.PushActivityTask"  
     android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

这里的process属性的名字和核心推送服务一样

  <!-- 配置SDK核心服务 -->  
  <service  
      android:name="com.igexin.sdk.PushService"  
      android:exported="true"  
      android:label="NotificationCenter"  
      android:process=":pushservice"> <!-- 这里也有process属性 -->  
      <intent-filter>  
          <action android:name="com.igexin.sdk.action.service.message"/>  
      </intent-filter>  
  </service>

然后我google了一下,这个属性的作用是:

  android:process  

  应在其中运行 Activity 的进程的名称。正常情况下,应用的所有组件都在为应用创建的默认进程名称内运行,您无需使用该属性。 但在必要时,您可以使用该属性替换默认进程名称,以便让应用组件散布到多个进程中。  
  如果为该属性分配的名称以冒号(“:”)开头,则会在需要时创建应用专用的新进程,并且 Activity 会在该进程中运行。如果进程名称以小写字符开头,Activity 将在该名称的全局进程中运行,前提是它拥有相应的权限。这可以让不同应用中的组件共享一个进程,从而减少资源占用。  

  <application> 元素的 process 属性可为所有组件设置一个不同的默认进程名称。

点击这里可以查看官方文档

所以,进行猜测,就因为主activity没有跑在 pushservice 进程里,才导致后台推送服务不能成功启动。

给主activity添加了

android:process=":pushservice"

这个属性,发现 NoticationCenter 进程正常启动了。并且应用后台化之后,服务正常运行,也能正常收到推送信息。

问题解决,不过不是很了解安卓开发,不知道这样会有什么副作用。不过目前看来,内存消耗和网络连接都正常,还没观察到什么严重后果。

前前后后花费了两个通宵和一个白天的时间,程序猿没人权啊~

继续阅读 »

【问题描述】

这个问题只在Andoid上出现,因为iOS端使用APNS,所以推送都能及时送达。

在使用个推推送时,一旦用户把应用切换到后台,那么推送的时候就会显示 success_offline 也就是 cilentID离线

而实际上,应用这时候还没有被系统杀死,但是再也无法接受到推送的消息。哪怕重新点开APP,也不会接受到消息,不管是之前的消息,还是从此之后推送的消息。

【解决方案】

首先,保证APP后台的进程没有被杀死。个推官方给出了各个系统的设置 点击这里查看

强烈大家先去读一读 蜡笔小鑫的《推送使用中的各种坑》 @蜡笔小鑫

  • 简单版

    如果不要求后台还能接收实时推送,只是想在用户重新点开APP时能够接受到之前的消息,并且让用户能够继续接收推送。那么只需要在APP切换到前台的时候,重新初始化个推sdk。

    代码如下:

    /**  
    * resume 应用从后台切换到前台的事件  
    */  
    document.addEventListener("resume", function() {  
    var pushManager = plus.android.importClass("com.igexin.sdk.PushManager");  
    var context = plus.android.runtimeMainActivity();  
    pushManager.getInstance().initialize(context);  
    }, false);
  • 复杂版

    如果想要后台还能实时接收推送,那么只能进行离线打包,修改项目的 AndroidManifest.xml 文件。

    增加一行代码,如下:

    <!-- 整段位置在225行左右 -->  
    <activity  
           android:name="io.dcloud.PandoraEntryActivity"  
           android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"  
           android:hardwareAccelerated="true"  
           android:label="5+Debug"  
           android:launchMode="singleTask"  
           android:screenOrientation="user"  
           android:process=":pushservice" <!-- 这一行就是增加的代码 -->  
           android:theme="@style/DCloudTheme"  
           android:windowSoftInputMode="adjustResize" >  
       </activity>

【解决过程】

原本以为是以为个推的SDK版本问题。5+SDK集成的个推版本是2.7.0.0,而现在官方发布的版本是2.9.3.0。但是把个推官方的SDK下载编译之后,后台仍然不能接受消息。

我用的开发机是小米5,在“更多应用”中检查的时候,发现当应用后台化的时候,“运行中”的应用列表中会显出APP的名字,显示“1个进程和0个服务”。 然后大概五秒钟后,应用就会从“运行中”列表消失,出现在“已缓存”的列表中。

但是个推的SDK是有一个后台服务的,名字叫做 NoticationCenter, 用来管理推送消息。也就是说,我们的应用没有成功唤起 NoticationCenter 这个服务。

但是鄙人只是了解过安卓开发的一点点知识 (web全栈就已经够费精力了好嘛~ 老板加工资好嘛~) ,只能尝试使用 Native.js 拉起个推的 PushService ,然并卵,失败了。

拉起服务的代码是这样的 :

  var main = plus.android.runtimeMainActivity();  
  var Intent = plus.android.importClass('android.content.Intent');  
  var intent = new Intent();  
  var serviceName = 'com.igexin.sdk.PushService';//把这里换成其他Service的名字,也可以实现拉取自定义的Service  
  intent.setClassName(main, serviceName);  
  main.startService(intent);

注 : 把serviceName换成 'com.igexin.sdk.PushServiceForUser', 能够拉起一个NoticationCenterForUser服务,原本以为是和PushService一样的,结果发现这个服务对于推送啥一点用都没有……

然后又进行对比,发现个推的官方Demo里,在 AndroidManifest.xml 里,对于SDK的两个activity又些许的差别。

第一部分:

 <!-- 第三方应用配置 -->  
 <activity  
     android:name=".GetuiSdkDemoActivity"  
     android:label="@string/app_name"  
     android:launchMode="singleTop" >  
     <intent-filter>  
         <action android:name="android.intent.action.MAIN" />  

         <category android:name="android.intent.category.LAUNCHER" />  
     </intent-filter>  
 </activity>

第二部分

<activity  
     android:name="com.igexin.sdk.GActivity"  
     android:excludeFromRecents="true"  
     android:exported="true"  
     android:process=":pushservice"  <!--就是这里,process属性-->  
     android:taskAffinity="com.igexin.sdk.PushActivityTask"  
     android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

这里的process属性的名字和核心推送服务一样

  <!-- 配置SDK核心服务 -->  
  <service  
      android:name="com.igexin.sdk.PushService"  
      android:exported="true"  
      android:label="NotificationCenter"  
      android:process=":pushservice"> <!-- 这里也有process属性 -->  
      <intent-filter>  
          <action android:name="com.igexin.sdk.action.service.message"/>  
      </intent-filter>  
  </service>

然后我google了一下,这个属性的作用是:

  android:process  

  应在其中运行 Activity 的进程的名称。正常情况下,应用的所有组件都在为应用创建的默认进程名称内运行,您无需使用该属性。 但在必要时,您可以使用该属性替换默认进程名称,以便让应用组件散布到多个进程中。  
  如果为该属性分配的名称以冒号(“:”)开头,则会在需要时创建应用专用的新进程,并且 Activity 会在该进程中运行。如果进程名称以小写字符开头,Activity 将在该名称的全局进程中运行,前提是它拥有相应的权限。这可以让不同应用中的组件共享一个进程,从而减少资源占用。  

  <application> 元素的 process 属性可为所有组件设置一个不同的默认进程名称。

点击这里可以查看官方文档

所以,进行猜测,就因为主activity没有跑在 pushservice 进程里,才导致后台推送服务不能成功启动。

给主activity添加了

android:process=":pushservice"

这个属性,发现 NoticationCenter 进程正常启动了。并且应用后台化之后,服务正常运行,也能正常收到推送信息。

问题解决,不过不是很了解安卓开发,不知道这样会有什么副作用。不过目前看来,内存消耗和网络连接都正常,还没观察到什么严重后果。

前前后后花费了两个通宵和一个白天的时间,程序猿没人权啊~

收起阅读 »

使用mask报Maximum call stack size exceeded错误

使用createMask方法创建蒙版时,传入的callback回调方法中不能包含手动关闭蒙版方法,也就是mask.close(),否则会无限递归自定义的callback,从而报Maximum call stack size exceeded错误。

使用createMask方法创建蒙版时,传入的callback回调方法中不能包含手动关闭蒙版方法,也就是mask.close(),否则会无限递归自定义的callback,从而报Maximum call stack size exceeded错误。

个推透传的一点心得体会

个推 分享

折腾了几天,终于搞定了安卓和ios下的个推透传推送,各种踩坑啊。
先来说说我想达到的目标,我要传送自定义的参数如文章id,然后实现页面的跳转。在安卓下,通过点击状态栏消息,跳转到指定id的页面,在ios下,分为2种情况,
1)app离线:推送的消息和安卓一样,在状态栏展现,通过点击实现跳转。
2)app在线:此时接收到的参数可以用一个confirm来询问是否跳转。

一、服务器端推送代码
首先来看看个推的推送模板,我是用php的。
function IGtTransmissionTemplateDemo(){
$template = new IGtTransmissionTemplate();
$template->set_appId(APPID);//应用appid
$template->set_appkey(APPKEY);//应用appkey
$template->set_transmissionType(1);//透传消息类型
$template->set_transmissionContent("测试离线ddd");//透传内容
//$template->set_duration(BEGINTIME,ENDTIME); //设置ANDROID客户端在此时间区间内展示消息

// 如下有两个推送模版,一个简单一个高级,可以互相切换使用。此处以高级为例,所以把简单模版注释掉。
// APN简单推送
// $apn = new IGtAPNPayload();
// $alertmsg=new SimpleAlertMsg();
// $alertmsg->alertMsg="";
// $apn->alertMsg=$alertmsg;
// $apn->badge=2;
// $apn->sound="";
// $apn->add_customMsg("payload","payload");
// $apn->contentAvailable=1;
// $apn->category="ACTIONABLE";
// $template->set_apnInfo($apn);
// APN高级推送
$apn = new IGtAPNPayload();
$alertmsg=new DictionaryAlertMsg();
$alertmsg->body="body";
$alertmsg->actionLocKey="ActionLockey";
$alertmsg->locKey="LocKey";
$alertmsg->locArgs=array("locargs");
$alertmsg->launchImage="launchimage";
// IOS8.2 支持
$alertmsg->title="水培喝水";
$alertmsg->titleLocKey="TitleLocKey";
$alertmsg->titleLocArgs=array("TitleLocArg");
$apn->alertMsg=$alertmsg;
$apn->badge=1;
$apn->sound="";
$apn->add_customMsg("payload","阿波罗度上市");
// $apn->contentAvailable=1;
$apn->category="ACTIONABLE";
$template->set_apnInfo($apn);
return $template;
}

二、推送参数
1)在线透传参数设置
$template->set_transmissionContent("测试离线ddd");这一行就是负责在线透传的,我们稍微改装下,填写入我们想要传送的自定义参数。
$template->set_transmissionContent('{"title":"文章标题","content":"正文内容","payload":{"id":"1","type":"新闻"}}');
2)离线透传参数设置
而 从 $apn = new IGtAPNPayload();这一行开始,构建的都是针对ios下app离线的推送
其中 $alertmsg->body="body"; 对应的是在线透传的content
$alertmsg->locKey="LocKey"; 对应的是在线透传的title
$alertmsg->title="水培喝水"; 对应的也是在线透传的title

然后 $apn->add_customMsg("payload","阿波罗度上市"); 这是用来传送自定义参数的,我们来改成我们想要的

$apn->add_customMsg("id","1");
$apn->add_customMsg("type","新闻");

三、客户端的解析
// 监听离线点击消息事件
plus.push.addEventListener("click", function(msg) {
var payload=(plus.os.name=='iOS')?msg.payload:JSON.parse(msg.payload);
pushGetRun(payload);
}, false);
// 监听在线消息事件
plus.push.addEventListener("receive", function(msg) {
if ( msg.payload ) {
if ( typeof(msg.payload)=="string" ) {
//alert( "payload(String): "+msg.payload );
} else {
var id = msg.payload.id;
var url = 'www/tpl/detail.html?id=' + id;
plus.nativeUI.confirm( "收到一条新消息,是否立即查看", function(e){
if(e.index==0){
mui.openWindow({
url: url,
id: 'notice' + id
});
}
}, "新消息通知", ["查看","忽略"] );
}
} else {
//alert( "payload: undefined" );
}
}, false);
});

function pushGetRun(payload) {
var id = payload.id;
var url = 'www/tpl/detail.html?id=' + id;
mui.openWindow({
url: url,
id: 'detail' + id
});
}

要注意的是在ios和安卓下,接收到的msg.payload解析不同,ios下是json数组,而安卓下却是string,需要转为json数组

继续阅读 »

折腾了几天,终于搞定了安卓和ios下的个推透传推送,各种踩坑啊。
先来说说我想达到的目标,我要传送自定义的参数如文章id,然后实现页面的跳转。在安卓下,通过点击状态栏消息,跳转到指定id的页面,在ios下,分为2种情况,
1)app离线:推送的消息和安卓一样,在状态栏展现,通过点击实现跳转。
2)app在线:此时接收到的参数可以用一个confirm来询问是否跳转。

一、服务器端推送代码
首先来看看个推的推送模板,我是用php的。
function IGtTransmissionTemplateDemo(){
$template = new IGtTransmissionTemplate();
$template->set_appId(APPID);//应用appid
$template->set_appkey(APPKEY);//应用appkey
$template->set_transmissionType(1);//透传消息类型
$template->set_transmissionContent("测试离线ddd");//透传内容
//$template->set_duration(BEGINTIME,ENDTIME); //设置ANDROID客户端在此时间区间内展示消息

// 如下有两个推送模版,一个简单一个高级,可以互相切换使用。此处以高级为例,所以把简单模版注释掉。
// APN简单推送
// $apn = new IGtAPNPayload();
// $alertmsg=new SimpleAlertMsg();
// $alertmsg->alertMsg="";
// $apn->alertMsg=$alertmsg;
// $apn->badge=2;
// $apn->sound="";
// $apn->add_customMsg("payload","payload");
// $apn->contentAvailable=1;
// $apn->category="ACTIONABLE";
// $template->set_apnInfo($apn);
// APN高级推送
$apn = new IGtAPNPayload();
$alertmsg=new DictionaryAlertMsg();
$alertmsg->body="body";
$alertmsg->actionLocKey="ActionLockey";
$alertmsg->locKey="LocKey";
$alertmsg->locArgs=array("locargs");
$alertmsg->launchImage="launchimage";
// IOS8.2 支持
$alertmsg->title="水培喝水";
$alertmsg->titleLocKey="TitleLocKey";
$alertmsg->titleLocArgs=array("TitleLocArg");
$apn->alertMsg=$alertmsg;
$apn->badge=1;
$apn->sound="";
$apn->add_customMsg("payload","阿波罗度上市");
// $apn->contentAvailable=1;
$apn->category="ACTIONABLE";
$template->set_apnInfo($apn);
return $template;
}

二、推送参数
1)在线透传参数设置
$template->set_transmissionContent("测试离线ddd");这一行就是负责在线透传的,我们稍微改装下,填写入我们想要传送的自定义参数。
$template->set_transmissionContent('{"title":"文章标题","content":"正文内容","payload":{"id":"1","type":"新闻"}}');
2)离线透传参数设置
而 从 $apn = new IGtAPNPayload();这一行开始,构建的都是针对ios下app离线的推送
其中 $alertmsg->body="body"; 对应的是在线透传的content
$alertmsg->locKey="LocKey"; 对应的是在线透传的title
$alertmsg->title="水培喝水"; 对应的也是在线透传的title

然后 $apn->add_customMsg("payload","阿波罗度上市"); 这是用来传送自定义参数的,我们来改成我们想要的

$apn->add_customMsg("id","1");
$apn->add_customMsg("type","新闻");

三、客户端的解析
// 监听离线点击消息事件
plus.push.addEventListener("click", function(msg) {
var payload=(plus.os.name=='iOS')?msg.payload:JSON.parse(msg.payload);
pushGetRun(payload);
}, false);
// 监听在线消息事件
plus.push.addEventListener("receive", function(msg) {
if ( msg.payload ) {
if ( typeof(msg.payload)=="string" ) {
//alert( "payload(String): "+msg.payload );
} else {
var id = msg.payload.id;
var url = 'www/tpl/detail.html?id=' + id;
plus.nativeUI.confirm( "收到一条新消息,是否立即查看", function(e){
if(e.index==0){
mui.openWindow({
url: url,
id: 'notice' + id
});
}
}, "新消息通知", ["查看","忽略"] );
}
} else {
//alert( "payload: undefined" );
}
}, false);
});

function pushGetRun(payload) {
var id = payload.id;
var url = 'www/tpl/detail.html?id=' + id;
mui.openWindow({
url: url,
id: 'detail' + id
});
}

要注意的是在ios和安卓下,接收到的msg.payload解析不同,ios下是json数组,而安卓下却是string,需要转为json数组

收起阅读 »

MUI详细文档----整理的各个样式说明与实例(持续更新中...)

mui

根据官方文档,然后自己学习的一个笔记整理成的文档,不断的完善希望能帮到大家
里面包含MUI详细样式的介绍,以及个个样式的详细介绍
文档内嵌JSFiddle,可以实时预览样例,自己上手练习。

文档地址:https://badfl.gitbooks.io/mui/content/

基本CSS样式:
列表\折叠面板
弹出菜单
按钮
卡片视图
输入框
单选框\/复选框
滑块
开关
数字输入框
数字角标
轮播组件
进度条
栅格
导航栏
侧滑菜单
选项卡

继续阅读 »

根据官方文档,然后自己学习的一个笔记整理成的文档,不断的完善希望能帮到大家
里面包含MUI详细样式的介绍,以及个个样式的详细介绍
文档内嵌JSFiddle,可以实时预览样例,自己上手练习。

文档地址:https://badfl.gitbooks.io/mui/content/

基本CSS样式:
列表\折叠面板
弹出菜单
按钮
卡片视图
输入框
单选框\/复选框
滑块
开关
数字输入框
数字角标
轮播组件
进度条
栅格
导航栏
侧滑菜单
选项卡

收起阅读 »

学习笔记自我小结(1)

===========ios 与 安卓 软键盘调用事件==============
javascript

var openSoftKeyboard = function() {  
                if(mui.os.ios) {  
                    var webView = plus.webview.currentWebview().nativeInstanceObject();  
                    webView.plusCallMethod({  
                        "setKeyboardDisplayRequiresUserAction": false  
                    });  
                } else {  
                    var webview = plus.android.currentWebview();  
                    plus.android.importClass(webview);  
                    webview.requestFocus();  
                    var Context = plus.android.importClass("android.content.Context");  
                    var InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager");  
                    var main = plus.android.runtimeMainActivity();  
                    var imm = main.getSystemService(Context.INPUT_METHOD_SERVICE);  
                    imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);  
                }  
            }  
            1.   
            mui.plusReady(function() {  
          //页面隐藏事件  
                plus.webview.currentWebview().addEventListener("hide",function(e){  
                    document.getElementById("search").value="";  
                    document.getElementById("search").blur();//搜索框取消焦点,关闭软键盘  
                });  
                //页面显示事件  
                plus.webview.currentWebview().addEventListener("show",function(e){  
                    setTimeout(function() {//自动打开软键盘,搜索框获取焦点  
                        openSoftKeyboard();  
                        document.getElementById("search").focus();  
                    }, 600);  
                    return false;  
                });  
})

ios 与 安卓 软键盘调用事件:
用于app商城首页点击搜索框,右滑出webview 搜索页面。
注意的bug: ajax 调用 、 createview 的创建 或者 销毁、plus.nativeUI 的 showWaiting() closeWaiting() 等等,会引起当前页面的聚焦问题,所以会导致blur()的触发,而blur()会自动调用native 的 软键盘关闭。
综上所述,由于各种原因导致失去焦点,引起软键盘闪退。

focus() 聚焦引起的软键盘闪退问题: 做适当的延迟就行了
setTimeout(function() {
mobile.focus();
}, 300)

软键盘的数字选项:(默认英文选项)
<input id="search" type="tel"/>

===========双击回退按钮后关闭app的方法================
//首页返回键处理
//处理逻辑:1秒内,连续两次按返回键,则退出应用;

var first = null;  
mui.back = function() {  
//首次按键,提示‘再按一次退出应用’  
if (!first) {  
 first = new Date().getTime();  
mui.toast('再按一次退出应用');  
setTimeout(function() {  
first = null;  
}, 1000);  
} else {  
if (new Date().getTime() - first < 1000) {  
plus.runtime.quit();  
}  
}  

};

真机调试(手机联调):(12/2)
明明方法正确,但是执行不了,遇到这个问题, 退出真机联调的app应用重新登录, 不需要重启服务器。
比如我预加载list页面,

mui.plusReady(function() {  
    var page = mui.preload({  
        url:'list.html',  //注意路径的配置(根据当前路径来配置)  
        id:'list.html',  
    })  

    mui.fire(page,'listPage',{  
        myId: "35467"  
    });    
});

在list 页面获取传过来的参数。


mui.plusReady(function () {  
    //添加infoEvn自定义事件监听  
    window.addEventListener('listPage',function(event){  
        //获得事件参数  
        var myId = event.detail.myId;  
        mui.alert("please waiting..."+ myId);  
        //plus.nativeUI.closeWaiting();  
        //根据id向服务器请求数据  
    });  
})

获取了好几次都没有获取到,不知道为什么? 重启了好几次真机app,才运行出来。。(或许是真机app有缓存?)

12/3

Uncaught RangeError: Maximum call stack size exceeded:

chrome 报堆栈错误
如果控制台报这个错误,可以在chrome中可以查看。

可能存在的原因: 可能是 html5+ 的 plus.ready 与 mui.plusReady 冲突。
一个页面,要么是 plus.ready 要么就是 mui.plusReady

顶部选项卡-可左右拖动+scroll区域滚动:

<div id="slider" class="mui-slider mui-fullscreen">
只需要在slider中添加一个mui-fullscreen就好

12/6

Uncaught RangeError: Maximum call stack size exceeded

chrome 报堆栈错误
如果控制台报这个错误,可以在chrome中可以查看。

可能存在的原因: 可能是 html5+ 的 plus.ready 与 mui.plusReady 冲突。
一个页面,要么是 plus.ready 要么就是 mui.plusReady

顶部选项卡-可左右拖动+scroll区域滚动

<div id="slider" class="mui-slider mui-fullscreen">
只需要在slider中添加一个mui-fullscreen就好

上拉加载:动态添加数据
一定要作用在 mui-scroll 的元素上: 如下
(仔细审查demo上的代码,严格按照demo上固有的代码结构还有js作用的元素来重新组织自己的代码)

$('#offCanvasContentScroll .mui-scroll').pullToRefresh({  
                    up: {  
                        callback: function() {  
                        var self = this;  
                            setTimeout(function() {    
                                mui.ajax("../json/china.json", {   
                                    type: "post",  
                                    dataType: "json",  
                                    timeout: 10000,//超时时间设置为10秒  
                                    success: function(data) {  
                                        var ul = self.element.querySelector('#pro-list');  
                                        ul.appendChild(createFragment());  
                                        self.endPullUpToRefresh();  
                                        lazyLoadApi.refresh(true);  
                                        bindProClick();  
                                    },  
                                    error: function(xhr,type,errorThrown) {  
                                        mui.alert("error: "+ type);  
                                    }  
                                });  
                            }, 70);    
                        }  
                    }  
                });  

各类组件如果是用动态添加数据或者追加数据的方式,导致组件无法触发,一般情况下,重新调用组件方法进行激活即可。

继续阅读 »

===========ios 与 安卓 软键盘调用事件==============
javascript

var openSoftKeyboard = function() {  
                if(mui.os.ios) {  
                    var webView = plus.webview.currentWebview().nativeInstanceObject();  
                    webView.plusCallMethod({  
                        "setKeyboardDisplayRequiresUserAction": false  
                    });  
                } else {  
                    var webview = plus.android.currentWebview();  
                    plus.android.importClass(webview);  
                    webview.requestFocus();  
                    var Context = plus.android.importClass("android.content.Context");  
                    var InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager");  
                    var main = plus.android.runtimeMainActivity();  
                    var imm = main.getSystemService(Context.INPUT_METHOD_SERVICE);  
                    imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);  
                }  
            }  
            1.   
            mui.plusReady(function() {  
          //页面隐藏事件  
                plus.webview.currentWebview().addEventListener("hide",function(e){  
                    document.getElementById("search").value="";  
                    document.getElementById("search").blur();//搜索框取消焦点,关闭软键盘  
                });  
                //页面显示事件  
                plus.webview.currentWebview().addEventListener("show",function(e){  
                    setTimeout(function() {//自动打开软键盘,搜索框获取焦点  
                        openSoftKeyboard();  
                        document.getElementById("search").focus();  
                    }, 600);  
                    return false;  
                });  
})

ios 与 安卓 软键盘调用事件:
用于app商城首页点击搜索框,右滑出webview 搜索页面。
注意的bug: ajax 调用 、 createview 的创建 或者 销毁、plus.nativeUI 的 showWaiting() closeWaiting() 等等,会引起当前页面的聚焦问题,所以会导致blur()的触发,而blur()会自动调用native 的 软键盘关闭。
综上所述,由于各种原因导致失去焦点,引起软键盘闪退。

focus() 聚焦引起的软键盘闪退问题: 做适当的延迟就行了
setTimeout(function() {
mobile.focus();
}, 300)

软键盘的数字选项:(默认英文选项)
<input id="search" type="tel"/>

===========双击回退按钮后关闭app的方法================
//首页返回键处理
//处理逻辑:1秒内,连续两次按返回键,则退出应用;

var first = null;  
mui.back = function() {  
//首次按键,提示‘再按一次退出应用’  
if (!first) {  
 first = new Date().getTime();  
mui.toast('再按一次退出应用');  
setTimeout(function() {  
first = null;  
}, 1000);  
} else {  
if (new Date().getTime() - first < 1000) {  
plus.runtime.quit();  
}  
}  

};

真机调试(手机联调):(12/2)
明明方法正确,但是执行不了,遇到这个问题, 退出真机联调的app应用重新登录, 不需要重启服务器。
比如我预加载list页面,

mui.plusReady(function() {  
    var page = mui.preload({  
        url:'list.html',  //注意路径的配置(根据当前路径来配置)  
        id:'list.html',  
    })  

    mui.fire(page,'listPage',{  
        myId: "35467"  
    });    
});

在list 页面获取传过来的参数。


mui.plusReady(function () {  
    //添加infoEvn自定义事件监听  
    window.addEventListener('listPage',function(event){  
        //获得事件参数  
        var myId = event.detail.myId;  
        mui.alert("please waiting..."+ myId);  
        //plus.nativeUI.closeWaiting();  
        //根据id向服务器请求数据  
    });  
})

获取了好几次都没有获取到,不知道为什么? 重启了好几次真机app,才运行出来。。(或许是真机app有缓存?)

12/3

Uncaught RangeError: Maximum call stack size exceeded:

chrome 报堆栈错误
如果控制台报这个错误,可以在chrome中可以查看。

可能存在的原因: 可能是 html5+ 的 plus.ready 与 mui.plusReady 冲突。
一个页面,要么是 plus.ready 要么就是 mui.plusReady

顶部选项卡-可左右拖动+scroll区域滚动:

<div id="slider" class="mui-slider mui-fullscreen">
只需要在slider中添加一个mui-fullscreen就好

12/6

Uncaught RangeError: Maximum call stack size exceeded

chrome 报堆栈错误
如果控制台报这个错误,可以在chrome中可以查看。

可能存在的原因: 可能是 html5+ 的 plus.ready 与 mui.plusReady 冲突。
一个页面,要么是 plus.ready 要么就是 mui.plusReady

顶部选项卡-可左右拖动+scroll区域滚动

<div id="slider" class="mui-slider mui-fullscreen">
只需要在slider中添加一个mui-fullscreen就好

上拉加载:动态添加数据
一定要作用在 mui-scroll 的元素上: 如下
(仔细审查demo上的代码,严格按照demo上固有的代码结构还有js作用的元素来重新组织自己的代码)

$('#offCanvasContentScroll .mui-scroll').pullToRefresh({  
                    up: {  
                        callback: function() {  
                        var self = this;  
                            setTimeout(function() {    
                                mui.ajax("../json/china.json", {   
                                    type: "post",  
                                    dataType: "json",  
                                    timeout: 10000,//超时时间设置为10秒  
                                    success: function(data) {  
                                        var ul = self.element.querySelector('#pro-list');  
                                        ul.appendChild(createFragment());  
                                        self.endPullUpToRefresh();  
                                        lazyLoadApi.refresh(true);  
                                        bindProClick();  
                                    },  
                                    error: function(xhr,type,errorThrown) {  
                                        mui.alert("error: "+ type);  
                                    }  
                                });  
                            }, 70);    
                        }  
                    }  
                });  

各类组件如果是用动态添加数据或者追加数据的方式,导致组件无法触发,一般情况下,重新调用组件方法进行激活即可。

收起阅读 »

老帖子已经关闭

老帖子已经关闭

老帖子已经关闭

iOS讯飞语音自定义界面

MUI的人没空回答只能看他们的插件源码自己写了,废话不多说代码如下:

JS脚本 xfyun-plugin.js文件  
;define(function(require, exports, module) {  
    var _BARCODE = 'XFYunPlugin',  
        B = window.plus.bridge;  

    var XFYunPlugin =   
    {  
        /**  
         * 开始语音识别  
         */  
        startListen : function (successCallback, errorCallback)  
        {  
            var success = typeof successCallback !== 'function' ? null : function(args)   
            {  
                successCallback(args);  
            },  
            fail = typeof errorCallback !== 'function' ? null : function(code)   
            {  
                errorCallback(code);  
            };  
            callbackID = B.callbackId(success, fail);  

            return B.exec(_BARCODE, "startListen", [callbackID]);  
        },  

        /**  
         * 停止语音识别  
         */  
        stopListen : function (successCallback, errorCallback)  
        {  
            var success = typeof successCallback !== 'function' ? null : function(args)   
            {  
                successCallback(args);  
            },  
            fail = typeof errorCallback !== 'function' ? null : function(code)   
            {  
                errorCallback(code);  
            };  
            callbackID = B.callbackId(success, fail);  

            return B.exec(_BARCODE, "stopListen", [callbackID]);  
        }  
    };  
    window.plus.XFYunPlugin = XFYunPlugin;  
});  

原生插件  
PGNXFYunPlugin.h文件  

#include "PGPlugin.h"  
#include "PGMethod.h"  
#import <Foundation/Foundation.h>  

// 讯飞  
#import "iflyMSC/IFlySpeechRecognizerDelegate.h"  
#import "iflyMSC/IFlySpeechRecognizer.h"  
#import "iflyMSC/IFlySpeechConstant.h"  
#import "iflyMSC/IFlySpeechError.h"  

@interface PGXFYunPlugin : PGPlugin<IFlySpeechRecognizerDelegate>  
{  
    IFlySpeechRecognizer *iflySpeechRecognizer;  
}  

@property(nonatomic, strong)NSString *callBackID;  
@property (nonatomic, assign) BOOL isSpeeching; // 是否正在录音  

// 开始语音识别  
- (void)startListen:(PGMethod *)command;  

// 停止语音识别  
- (void)stopListen:(PGMethod *)command;  

@end  

PGNXFYunPlugin.m文件  

#import "PGXFYunPlugin.h"  

@implementation PGXFYunPlugin  

@synthesize callBackID;  
@synthesize isSpeeching;  

// 开始语音识别  
- (void)startListen:(PGMethod *)command  
{  

    if (command && !self.isSpeeching) {  
        // CallBackid 异步方法的回调id,H5+ 会根据回调ID通知JS层运行结果成功或者失败  
        NSString *cbId = [command.arguments objectAtIndex:0];  

        self.callBackID = cbId;  
        self.isSpeeching = YES;  

        // 创建语音听写对象  
        if (iflySpeechRecognizer == nil) {  
            iflySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];  
            [iflySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];  

            // 设置听写参数  
            [iflySpeechRecognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];  
            //asr_audio_path保存录音文件名,如不再需要,设置value为nil表示取消,默认目录是Library/cache  
            [iflySpeechRecognizer setParameter:nil forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];  
            //设置最长录音时间12s  
            [iflySpeechRecognizer setParameter:@"12000" forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];  
            //网络等待时间30s  
            [iflySpeechRecognizer setParameter:@"20000" forKey:[IFlySpeechConstant NET_TIMEOUT]];  
            //设置是否返回标点符号  
            [iflySpeechRecognizer setParameter:@"0" forKey:[IFlySpeechConstant ASR_PTT]];  
        }  
        iflySpeechRecognizer.delegate = self;  

        // 启动识别服务  
        [iflySpeechRecognizer startListening];  

    }  

}  

// 停止语音识别  
- (void)stopListen:(PGMethod *)command {  
    if (command) {  

        self.isSpeeching = NO;  
        if (iflySpeechRecognizer != nil) {  
            // 停止识别服务  
            [iflySpeechRecognizer stopListening];  

        }  

    }  
}  

#pragma mark IFlySpeechRecognizerDelegate.h delegate  

/*  
 识别结果返回代理  
*/  
- (void)onResults:(NSArray *)results isLast:(BOOL)isLast  
{  
    NSLog(@"onResults");  

    self.isSpeeching = NO;  

    if (self.callBackID != nil) {  

        NSMutableString *resultMutableString = [[NSMutableString alloc] init];  
        NSDictionary *dic = results[0];  
        for (NSString *key in dic) {  
            [resultMutableString appendFormat:@"%@",key];  
        }  
        NSString *resultString = [NSString stringWithFormat:@"%@", resultMutableString];  
        NSString *resultFromJson =  [self stringFromJson:resultString];  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"type",   @"text",  
                                   @"value", resultFromJson,  
                                   nil];  

        // 运行Native代码结果和预期相同,调用回调通知JS层运行成功并返回结果  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  

}  

/*  
 识别会话结束返回代理 (注:无论听写是否正确都会回调)  
 error.errorCode =  
 0     听写正确  
 other 听写出错  
 */  
- (void) onError:(IFlySpeechError *) error  
{  
    NSLog(@"onError");  

    self.isSpeeching = NO;  

    if (error.errorCode != 0 && self.callBackID != nil ) {  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"code", [NSString stringWithFormat:@"%d", error.errorCode],  
                                   @"desc", error.errorDesc,  
                                   nil];  

        // 如果Native代码运行结果和预期不同,需要通过回调通知JS层出现错误,并返回错误提示  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusError messageAsDictionary:dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  

}  

/*  
 开始录音回调  
 */  
- (void)onBeginOfSpeech  
{  
    NSLog(@"onBeginOfSpeech");  
}  

/*  
 停止录音回调  
*/  
- (void)onEndOfSpeech  
{  
    NSLog(@"onEndOfSpeech");  

    self.isSpeeching = NO;  
}  

/*  
 音量回调函数  
 volume 0-30  
 */  
- (void)onVolumeChanged:(int)volume  
{  
    if (self.callBackID != nil ) {  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"type",   @"volume",  
                                   @"value", [NSString stringWithFormat:@"%d", volume],  
                                   nil];  

        // 运行Native代码结果和预期相同,调用回调通知JS层运行成功并返回结果  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary: dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  
}  

- (void)dealloc {  
    [super dealloc];  

    [iflySpeechRecognizer cancel]; //取消识别  
    [iflySpeechRecognizer setDelegate:nil];  
    [iflySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];  

    self.callBackID = nil;  
    self.isSpeeching = nil;  
}  

/**  
 解析听写json格式的数据  
 params例如:  
 {"sn":1,"ls":true,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"w":"白日","sc":0}]},{"bg":0,"cw":[{"w":"依山","sc":0}]},{"bg":0,"cw":[{"w":"尽","sc":0}]},{"bg":0,"cw":[{"w":"黄河入海流","sc":0}]},{"bg":0,"cw":[{"w":"。","sc":0}]}]}  
 ****/  
- (NSString *)stringFromJson:(NSString*)params  
{  
    if (params == NULL) {  
        return nil;  
    }  

    NSMutableString *tempStr = [[NSMutableString alloc] init];  
    NSDictionary *resultDic  = [NSJSONSerialization JSONObjectWithData:    //返回的格式必须为utf8的,否则发生未知错误  
                                [params dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];  

    if (resultDic!= nil) {  
        NSArray *wordArray = [resultDic objectForKey:@"ws"];  

        for (int i = 0; i < [wordArray count]; i++) {  
            NSDictionary *wsDic = [wordArray objectAtIndex: i];  
            NSArray *cwArray = [wsDic objectForKey:@"cw"];  

            for (int j = 0; j < [cwArray count]; j++) {  
                NSDictionary *wDic = [cwArray objectAtIndex:j];  
                NSString *str = [wDic objectForKey:@"w"];  
                [tempStr appendString: str];  
            }  
        }  
    }  
    return tempStr;  
}  

@end  

// 调用方法  
plus.XFYunPlugin.startListen(function(result) {  
// 成功回调函数  
JSON.stringify(result);  
}, function(error) {  
// 失败回调函数  
JSON.stringify(error);  
});  
继续阅读 »

MUI的人没空回答只能看他们的插件源码自己写了,废话不多说代码如下:

JS脚本 xfyun-plugin.js文件  
;define(function(require, exports, module) {  
    var _BARCODE = 'XFYunPlugin',  
        B = window.plus.bridge;  

    var XFYunPlugin =   
    {  
        /**  
         * 开始语音识别  
         */  
        startListen : function (successCallback, errorCallback)  
        {  
            var success = typeof successCallback !== 'function' ? null : function(args)   
            {  
                successCallback(args);  
            },  
            fail = typeof errorCallback !== 'function' ? null : function(code)   
            {  
                errorCallback(code);  
            };  
            callbackID = B.callbackId(success, fail);  

            return B.exec(_BARCODE, "startListen", [callbackID]);  
        },  

        /**  
         * 停止语音识别  
         */  
        stopListen : function (successCallback, errorCallback)  
        {  
            var success = typeof successCallback !== 'function' ? null : function(args)   
            {  
                successCallback(args);  
            },  
            fail = typeof errorCallback !== 'function' ? null : function(code)   
            {  
                errorCallback(code);  
            };  
            callbackID = B.callbackId(success, fail);  

            return B.exec(_BARCODE, "stopListen", [callbackID]);  
        }  
    };  
    window.plus.XFYunPlugin = XFYunPlugin;  
});  

原生插件  
PGNXFYunPlugin.h文件  

#include "PGPlugin.h"  
#include "PGMethod.h"  
#import <Foundation/Foundation.h>  

// 讯飞  
#import "iflyMSC/IFlySpeechRecognizerDelegate.h"  
#import "iflyMSC/IFlySpeechRecognizer.h"  
#import "iflyMSC/IFlySpeechConstant.h"  
#import "iflyMSC/IFlySpeechError.h"  

@interface PGXFYunPlugin : PGPlugin<IFlySpeechRecognizerDelegate>  
{  
    IFlySpeechRecognizer *iflySpeechRecognizer;  
}  

@property(nonatomic, strong)NSString *callBackID;  
@property (nonatomic, assign) BOOL isSpeeching; // 是否正在录音  

// 开始语音识别  
- (void)startListen:(PGMethod *)command;  

// 停止语音识别  
- (void)stopListen:(PGMethod *)command;  

@end  

PGNXFYunPlugin.m文件  

#import "PGXFYunPlugin.h"  

@implementation PGXFYunPlugin  

@synthesize callBackID;  
@synthesize isSpeeching;  

// 开始语音识别  
- (void)startListen:(PGMethod *)command  
{  

    if (command && !self.isSpeeching) {  
        // CallBackid 异步方法的回调id,H5+ 会根据回调ID通知JS层运行结果成功或者失败  
        NSString *cbId = [command.arguments objectAtIndex:0];  

        self.callBackID = cbId;  
        self.isSpeeching = YES;  

        // 创建语音听写对象  
        if (iflySpeechRecognizer == nil) {  
            iflySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];  
            [iflySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];  

            // 设置听写参数  
            [iflySpeechRecognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];  
            //asr_audio_path保存录音文件名,如不再需要,设置value为nil表示取消,默认目录是Library/cache  
            [iflySpeechRecognizer setParameter:nil forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];  
            //设置最长录音时间12s  
            [iflySpeechRecognizer setParameter:@"12000" forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];  
            //网络等待时间30s  
            [iflySpeechRecognizer setParameter:@"20000" forKey:[IFlySpeechConstant NET_TIMEOUT]];  
            //设置是否返回标点符号  
            [iflySpeechRecognizer setParameter:@"0" forKey:[IFlySpeechConstant ASR_PTT]];  
        }  
        iflySpeechRecognizer.delegate = self;  

        // 启动识别服务  
        [iflySpeechRecognizer startListening];  

    }  

}  

// 停止语音识别  
- (void)stopListen:(PGMethod *)command {  
    if (command) {  

        self.isSpeeching = NO;  
        if (iflySpeechRecognizer != nil) {  
            // 停止识别服务  
            [iflySpeechRecognizer stopListening];  

        }  

    }  
}  

#pragma mark IFlySpeechRecognizerDelegate.h delegate  

/*  
 识别结果返回代理  
*/  
- (void)onResults:(NSArray *)results isLast:(BOOL)isLast  
{  
    NSLog(@"onResults");  

    self.isSpeeching = NO;  

    if (self.callBackID != nil) {  

        NSMutableString *resultMutableString = [[NSMutableString alloc] init];  
        NSDictionary *dic = results[0];  
        for (NSString *key in dic) {  
            [resultMutableString appendFormat:@"%@",key];  
        }  
        NSString *resultString = [NSString stringWithFormat:@"%@", resultMutableString];  
        NSString *resultFromJson =  [self stringFromJson:resultString];  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"type",   @"text",  
                                   @"value", resultFromJson,  
                                   nil];  

        // 运行Native代码结果和预期相同,调用回调通知JS层运行成功并返回结果  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  

}  

/*  
 识别会话结束返回代理 (注:无论听写是否正确都会回调)  
 error.errorCode =  
 0     听写正确  
 other 听写出错  
 */  
- (void) onError:(IFlySpeechError *) error  
{  
    NSLog(@"onError");  

    self.isSpeeching = NO;  

    if (error.errorCode != 0 && self.callBackID != nil ) {  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"code", [NSString stringWithFormat:@"%d", error.errorCode],  
                                   @"desc", error.errorDesc,  
                                   nil];  

        // 如果Native代码运行结果和预期不同,需要通过回调通知JS层出现错误,并返回错误提示  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusError messageAsDictionary:dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  

}  

/*  
 开始录音回调  
 */  
- (void)onBeginOfSpeech  
{  
    NSLog(@"onBeginOfSpeech");  
}  

/*  
 停止录音回调  
*/  
- (void)onEndOfSpeech  
{  
    NSLog(@"onEndOfSpeech");  

    self.isSpeeching = NO;  
}  

/*  
 音量回调函数  
 volume 0-30  
 */  
- (void)onVolumeChanged:(int)volume  
{  
    if (self.callBackID != nil ) {  

        NSDictionary *dicResult = [NSDictionary dictionaryWithObjectsAndKeys:  
                                   @"type",   @"volume",  
                                   @"value", [NSString stringWithFormat:@"%d", volume],  
                                   nil];  

        // 运行Native代码结果和预期相同,调用回调通知JS层运行成功并返回结果  
        PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary: dicResult];  

        // 通知JS层Native层运行结果,JS Pluginbridge会根据cbid找到对应的回调方法并触发  
        [self toCallback:self.callBackID withReslut:[result toJSONString]];  
    }  
}  

- (void)dealloc {  
    [super dealloc];  

    [iflySpeechRecognizer cancel]; //取消识别  
    [iflySpeechRecognizer setDelegate:nil];  
    [iflySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];  

    self.callBackID = nil;  
    self.isSpeeching = nil;  
}  

/**  
 解析听写json格式的数据  
 params例如:  
 {"sn":1,"ls":true,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"w":"白日","sc":0}]},{"bg":0,"cw":[{"w":"依山","sc":0}]},{"bg":0,"cw":[{"w":"尽","sc":0}]},{"bg":0,"cw":[{"w":"黄河入海流","sc":0}]},{"bg":0,"cw":[{"w":"。","sc":0}]}]}  
 ****/  
- (NSString *)stringFromJson:(NSString*)params  
{  
    if (params == NULL) {  
        return nil;  
    }  

    NSMutableString *tempStr = [[NSMutableString alloc] init];  
    NSDictionary *resultDic  = [NSJSONSerialization JSONObjectWithData:    //返回的格式必须为utf8的,否则发生未知错误  
                                [params dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];  

    if (resultDic!= nil) {  
        NSArray *wordArray = [resultDic objectForKey:@"ws"];  

        for (int i = 0; i < [wordArray count]; i++) {  
            NSDictionary *wsDic = [wordArray objectAtIndex: i];  
            NSArray *cwArray = [wsDic objectForKey:@"cw"];  

            for (int j = 0; j < [cwArray count]; j++) {  
                NSDictionary *wDic = [cwArray objectAtIndex:j];  
                NSString *str = [wDic objectForKey:@"w"];  
                [tempStr appendString: str];  
            }  
        }  
    }  
    return tempStr;  
}  

@end  

// 调用方法  
plus.XFYunPlugin.startListen(function(result) {  
// 成功回调函数  
JSON.stringify(result);  
}, function(error) {  
// 失败回调函数  
JSON.stringify(error);  
});  
收起阅读 »

mui原生日期选择器封装

分享插件 插件

插件js

/*  时间选择器封装 @山东-三言  
 *  共有两种初始化方式:  
 *  @第一种方式:mui(".mui-getDate").getDateInfo();       类名可以随便定义,优点可以定义多项,缺点无法设置回调函数  
 *  @第二种方式:var test = new mui.getDateInfo(document.getElementById("testGetDate"),function(d){alert(d)});      
 *      @第一个参数为element类型,就是要初始化的节点  
 *      @第二个参数为function类型,回调函数,回调的有一个参数为获取的时间字符串  
 * ------------------------------------------------------------  
 *  时间类型说明              例子  
 *  data命名  data-dateType   <input class="mui-getDate" data-dateType="date" id='' name=''>  
 *                
 *  可选值 返回结果说明  
 *  date    日期类型,例如 2016-11-11  
 *  time    时间类型,例如 18:22       24小时制  
 *  @! 如果不设置data-dateType默认为date类型  
 * ------------------------------------------------------------  
 * 【data-dateType为date类型】    !!!刚给data-minDate和data-maxDate增加了一个active的值,如果传active可以设置为当前日期  
 * data参数名              说明          默认值 格式都为"2016-11-11"      
 * data-defaultDate     默认选中的时间 当前日期  
 * data-minDate         日期最小值       无  
 * data-maxDate         日期最大值       无  
 *   
 * 【data-dateType为time类型】  
 * data参数名              说明                  默认值 格式都为"13:22"   
 * data-defaultDate     data-defaultDate    12:00     
 * -----------------------------------------------------------  
 * 返回值  如果有回调函数会调用回调函数,返回值为选中的日期字符串  
 *      当element为input的时候会设置value为选中的日期字符串  
 */  
(function($) {  
    var GetDateInfo = $.getDateInfo = $.Class.extend({  
        init: function(element, fun) {  
            var self = this;  
            if(element.nodeType) {  
                self.ele = element;  
                fun && (self.fun = fun);  
                self.EventInit();  
            } else {  
                throw new Error('传入的参数不是Element类型!');  
            }  
            return self;  
        },  
        //绑定事件  
        EventInit: function() {  
            var self = this,  
                selfEle = this.ele,  
                isBindingEvent = selfEle.hasAttribute("data-getDate-event"); //是否绑定点击事件  
            !isBindingEvent && selfEle.addEventListener("tap", function() {  
                self.getDate()  
            }), selfEle.setAttribute("data-getDate-event", true); //绑定点击事件  
            !selfEle.hasAttribute("readonly") && selfEle.tagName == 'INPUT' && selfEle.setAttribute("readonly", "readonly"); //如果是INPUT添加禁用状态  
            return self;  
        },  

        /*为了不犯和官方numbox插件不能动态设置最大值和最小值的错误,本插件采用的都是实时获取attr的值*/  
        getDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDateType = selfEle.getAttribute("data-dateType") || "date";  
                attrDateType == "date" && self.setDate();  
                attrDateType == "time" && self.setTime();  
            return self;  
        },  
        setDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultDate = selfEle.getAttribute("data-defaultDate"), //获取attr设置的当前日期  
                dDate = new Date(), //当前日期对象  
                activeDate = [dDate.getFullYear(), dDate.getMonth(), dDate.getDate()], //获取当前日期  
                attrMinDate = selfEle.getAttribute("data-minDate"), //获取最小日期  
                attrMaxDate = selfEle.getAttribute("data-maxDate"), //获取最大日期  
                minDate, maxDate; //最大值、最大值对象  

            /*设置默认日期*/  
            attrDefaultDate ? dDate = self.setDateStr(attrDefaultDate) : dDate.setFullYear(activeDate[0], activeDate[1], activeDate[2]);  
            /*设置最小日期*/  
            attrMinDate && (minDate = attrMinDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMinDate));  
            /*设置最大日期*/  
            attrMaxDate && (maxDate = attrMaxDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMaxDate));  

            plus && plus.nativeUI.pickDate(function(e) {  
                var d = e.date,  
                    dStr = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();  

                selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                self.fun && self.fun(dStr);  
            }, function(e) {  

            }, {  
                title: "请选择日期",  
                date: dDate,  
                minDate: minDate,  
                maxDate: maxDate  
            });  
            return self;  
        },  
        setTime: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultTime = selfEle.getAttribute("data-defaultTime")?selfEle.getAttribute("data-defaultTime").split(":"):null,  
                dTime = new Date();  

            attrDefaultTime?dTime.setHours(attrDefaultTime[0], attrDefaultTime[1]):dTime.setHours(12, 0);  
            plus.nativeUI.pickTime(function(e) {  
                var d = e.date,  
                    dStr = d.getHours() + ":" + d.getMinutes();  

                selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                self.fun && self.fun(dStr);  
            }, function(e) {  

            }, {  
                title: "请选择时间",  
                is24Hour: true,  
                time: dTime  
            });  
            return self;  
        },  
        setDateStr: function(str) {  
            if(typeof str === 'string') {  
                var returnAry = str.split("-").map(function(item, index) {  
                    if(index == 1) {  
                        return +item - 1;  
                    } else {  
                        return +item;  
                    }  
                });  
                var dateObj = new Date();  
                dateObj.setFullYear(returnAry[0], returnAry[1], returnAry[2]);  
                return dateObj;  
            } else {  
                throw new Error('传入的参数不是字符串类型!');  
            }  
        },  
        setDateObj: function(dateAry){  
            var d = new Date();  
                d.setFullYear(dateAry[0],dateAry[1],dateAry[2]);  
            return d;  
        }  
    });  

    $.fn.getDateInfo = function() {  
        this.each(function(i, item) {  
            if(item.GetDateInfo) {  
                return false;  
            } else {  
                item.getDateInfo = new GetDateInfo(item);  
                return true;  
            }  
        });  
    };  
})(mui);

前台代码

<!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="css/mui.min.css" rel="stylesheet" />  
        <script type="text/javascript" charset="utf-8">  
            mui.init();  
        </script>  
        <style type="text/css">  
            #test2 {  
                margin: 20px auto;  
                width: 300px;  
                background-color: #007AFF;  
                padding: 10px;  
                color: #fff;  
                margin-bottom: 15px;  
                border-radius: 4px;  
                text-align: center;  
            }  
            input {  
-webkit-user-select: auto !important;  
}  
        </style>  
    </head>  

    <body>  
        <form class="mui-input-group">  
            <span style="display: block;text-align: center;line-height: 40px;color:#0062CC;background-color: #f7f7f7;;">本插件只在app中有效</span>  
            <div class="mui-input-row">  
                <label>无data参数</label>  
                <input type="text" class="mui-input-clear " placeholder="无data参数">  
            </div>  
            <div class="mui-input-row">  
                <label>选择日期</label>  
                <input type="text" data-dateType="date" class="mui-input-clear" placeholder="选择日期">  
            </div>  
            <div class="mui-input-row">  
                <label>选择时间</label>  
                <input type="text" data-dateType="time" class="mui-input-clear" placeholder="选择时间">  
            </div>  
            <div class="mui-input-row">  
                <label>日期默认值</label>  
                <input type="text" data-defaultDate="2016-11-11" class="mui-input-clear" placeholder="日期默认值">  
            </div>  
            <div class="mui-input-row">  
                <label style="width: 60%;">日期默认、最大最小值</label>  
                <input class="mui-input-clear" data-defaultDate="2016-11-11" data-minDate="2016-11-2" data-maxDate="2016-11-28" placeholder="日期默认、最大最小值" style="width:40%" type="text">  
            </div>  
            <div class="mui-input-row">  
                <label style="width: 50%;">dateTime类型</label>  
                <input class="mui-input-clear" data-dateType="dateTime" data-defaultDate="2016-11-11" data-minDate="2016-11-2" data-maxDate="2016-11-28" data-defaultTime="18:22" placeholder="dateTime类型" style="width:50%" type="text">  
            </div>  
            <div class="mui-input-row">  
                <label>时间默认,</label>  
                <input class="mui-input-clear" data-dateType="time" data-defaultTime="16:32" placeholder="时间默认" type="text">  
            </div>  

            <div id="test2" data-dateType="time">选择时间,动态设置,支持任何参数设置</div>  
            <p class="mui-text-center">更多的组合效果等你来发掘!</p>  
            <script src="js/getDate.js" type="text/javascript" charset="utf-8"></script>  
            <script type="text/javascript">  
                mui.plusReady(function() {  
                    //第一种方法调用,可以为N个元素绑定日期选择  
                    mui("input").getDateInfo();  
                    //第二种方法,可以设置回调函数,第一个返回值为日期字符串,第二个是返回当前的element  

                    var test = new mui.getDateInfo(document.getElementById("test2"), function(d, el) {  
                        //切换状态  
                        var state = el.getAttribute("data-dateType") == "time" ? "date" : "time";  
                        alert("选择的日期为:" + d + "\n我的状态变成了:" + state + "\n在单击下我试试看");  
                        //设置状态  
                        el.setAttribute("data-dateType", state);  
                    });  
                });  
            </script>  
        </form>  
    </body>  

</html>

2016-11-25日更新日志
·增加了新的data-dateType类型 "dateTime"
支持可以同时选择日期和时间,各项设置参数都通用

下面是修改后的js源码

(function($) {  
    var GetDateInfo = $.getDateInfo = $.Class.extend({  
        init: function(element, fun) {  
            var self = this;  
            if(element.nodeType) {  
                self.ele = element;  
                fun && (self.fun = fun);  
                self.EventInit();  
            } else {  
                throw new Error('传入的参数不是Element类型!');  
            }  
            return self;  
        },  
        //绑定事件  
        EventInit: function() {  
            var self = this,  
                selfEle = this.ele,  
                isBindingEvent = selfEle.hasAttribute("data-getDate-event"); //是否绑定点击事件  
            !isBindingEvent && selfEle.addEventListener("tap", function() {  
                self.getDate()  
            }), selfEle.setAttribute("data-getDate-event", true); //绑定点击事件  
            !selfEle.hasAttribute("readonly") && selfEle.tagName == 'INPUT' && selfEle.setAttribute("readonly", "readonly"); //如果是INPUT添加禁用状态  
            return self;  
        },  

        /*为了不犯和官方numbox插件不能动态设置最大值和最小值的错误,本插件采用的都是实时获取attr的值*/  
        getDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDateType = self.dateType = selfEle.getAttribute("data-dateType") || "date";  
                attrDateType == "date" && self.setDate();  
                attrDateType == "time" && self.setTime();  
                attrDateType == "dateTime" && self.setDateTime();  
            return self;  
        },  
        setDate: function(fn) {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultDate = selfEle.getAttribute("data-defaultDate"), //获取attr设置的当前日期  
                dDate = new Date(), //当前日期对象  
                activeDate = [dDate.getFullYear(), dDate.getMonth(), dDate.getDate()], //获取当前日期  
                attrMinDate = selfEle.getAttribute("data-minDate"), //获取最小日期  
                attrMaxDate = selfEle.getAttribute("data-maxDate"), //获取最大日期  
                minDate, maxDate; //最大值、最大值对象  

            /*设置默认日期*/  
            attrDefaultDate ? dDate = self.setDateStr(attrDefaultDate) : dDate.setFullYear(activeDate[0], activeDate[1], activeDate[2]);  
            /*设置最小日期*/  
            attrMinDate && (minDate = attrMinDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMinDate));  
            /*设置最大日期*/  
            attrMaxDate && (maxDate = attrMaxDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMaxDate));  

            plus && plus.nativeUI.pickDate(function(e) {  
                var d = e.date,  
                    dStr = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();  

                if(self.dateType == 'dateTime'){  
                    fn && fn(dStr);  
                }else{  
                    selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                    self.fun && self.fun(dStr);  
                }  
            }, function(e) {  

            }, {  
                title: "请选择日期",  
                date: dDate,  
                minDate: minDate,  
                maxDate: maxDate  
            });  
        },  
        setTime: function(fn) {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultTime = selfEle.getAttribute("data-defaultTime")?selfEle.getAttribute("data-defaultTime").split(":"):null,  
                dTime = new Date();  

            attrDefaultTime?dTime.setHours(attrDefaultTime[0], attrDefaultTime[1]):dTime.setHours(12, 0);  
            plus.nativeUI.pickTime(function(e) {  
                var d = e.date,  
                    dStr = d.getHours() + ":" + d.getMinutes();  

                if(self.dateType == 'dateTime'){  
                    fn && fn(dStr);  
                }else{  
                    selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                    self.fun && self.fun(dStr);  
                }  
            }, function(e) {  

            }, {  
                title: "请选择时间",  
                is24Hour: true,  
                time: dTime  
            });  
            return self;  
        },  
        setDateTime:function(){  
            var self = this,  
                selfEle = self.ele,  
                returnDateStr = '';  
            self.setDate(function(str){  
                returnDateStr = str;  
                self.setTime(function(str){  
                    returnDateStr +=' '+str;  
                    selfEle.tagName == 'INPUT' && (selfEle.value = returnDateStr);  
                    self.fun && self.fun(returnDateStr);  
                });  
            })  
        },  
        setDateStr: function(str) {  
            if(typeof str === 'string') {  
                var returnAry = str.split("-").map(function(item, index) {  
                    if(index == 1) {  
                        return +item - 1;  
                    } else {  
                        return +item;  
                    }  
                });  
                var dateObj = new Date();  
                dateObj.setFullYear(returnAry[0], returnAry[1], returnAry[2]);  
                return dateObj;  
            } else {  
                throw new Error('传入的参数不是字符串类型!');  
            }  
        },  
        setDateObj: function(dateAry){  
            var d = new Date();  
                d.setFullYear(dateAry[0],dateAry[1],dateAry[2]);  
            return d;  
        }  
    });  

    $.fn.getDateInfo = function() {  
        this.each(function(i, item) {  
            if(item.GetDateInfo) {  
                return false;  
            } else {  
                item.getDateInfo = new GetDateInfo(item);  
                return true;  
            }  
        });  
    };  
})(mui);
继续阅读 »

插件js

/*  时间选择器封装 @山东-三言  
 *  共有两种初始化方式:  
 *  @第一种方式:mui(".mui-getDate").getDateInfo();       类名可以随便定义,优点可以定义多项,缺点无法设置回调函数  
 *  @第二种方式:var test = new mui.getDateInfo(document.getElementById("testGetDate"),function(d){alert(d)});      
 *      @第一个参数为element类型,就是要初始化的节点  
 *      @第二个参数为function类型,回调函数,回调的有一个参数为获取的时间字符串  
 * ------------------------------------------------------------  
 *  时间类型说明              例子  
 *  data命名  data-dateType   <input class="mui-getDate" data-dateType="date" id='' name=''>  
 *                
 *  可选值 返回结果说明  
 *  date    日期类型,例如 2016-11-11  
 *  time    时间类型,例如 18:22       24小时制  
 *  @! 如果不设置data-dateType默认为date类型  
 * ------------------------------------------------------------  
 * 【data-dateType为date类型】    !!!刚给data-minDate和data-maxDate增加了一个active的值,如果传active可以设置为当前日期  
 * data参数名              说明          默认值 格式都为"2016-11-11"      
 * data-defaultDate     默认选中的时间 当前日期  
 * data-minDate         日期最小值       无  
 * data-maxDate         日期最大值       无  
 *   
 * 【data-dateType为time类型】  
 * data参数名              说明                  默认值 格式都为"13:22"   
 * data-defaultDate     data-defaultDate    12:00     
 * -----------------------------------------------------------  
 * 返回值  如果有回调函数会调用回调函数,返回值为选中的日期字符串  
 *      当element为input的时候会设置value为选中的日期字符串  
 */  
(function($) {  
    var GetDateInfo = $.getDateInfo = $.Class.extend({  
        init: function(element, fun) {  
            var self = this;  
            if(element.nodeType) {  
                self.ele = element;  
                fun && (self.fun = fun);  
                self.EventInit();  
            } else {  
                throw new Error('传入的参数不是Element类型!');  
            }  
            return self;  
        },  
        //绑定事件  
        EventInit: function() {  
            var self = this,  
                selfEle = this.ele,  
                isBindingEvent = selfEle.hasAttribute("data-getDate-event"); //是否绑定点击事件  
            !isBindingEvent && selfEle.addEventListener("tap", function() {  
                self.getDate()  
            }), selfEle.setAttribute("data-getDate-event", true); //绑定点击事件  
            !selfEle.hasAttribute("readonly") && selfEle.tagName == 'INPUT' && selfEle.setAttribute("readonly", "readonly"); //如果是INPUT添加禁用状态  
            return self;  
        },  

        /*为了不犯和官方numbox插件不能动态设置最大值和最小值的错误,本插件采用的都是实时获取attr的值*/  
        getDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDateType = selfEle.getAttribute("data-dateType") || "date";  
                attrDateType == "date" && self.setDate();  
                attrDateType == "time" && self.setTime();  
            return self;  
        },  
        setDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultDate = selfEle.getAttribute("data-defaultDate"), //获取attr设置的当前日期  
                dDate = new Date(), //当前日期对象  
                activeDate = [dDate.getFullYear(), dDate.getMonth(), dDate.getDate()], //获取当前日期  
                attrMinDate = selfEle.getAttribute("data-minDate"), //获取最小日期  
                attrMaxDate = selfEle.getAttribute("data-maxDate"), //获取最大日期  
                minDate, maxDate; //最大值、最大值对象  

            /*设置默认日期*/  
            attrDefaultDate ? dDate = self.setDateStr(attrDefaultDate) : dDate.setFullYear(activeDate[0], activeDate[1], activeDate[2]);  
            /*设置最小日期*/  
            attrMinDate && (minDate = attrMinDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMinDate));  
            /*设置最大日期*/  
            attrMaxDate && (maxDate = attrMaxDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMaxDate));  

            plus && plus.nativeUI.pickDate(function(e) {  
                var d = e.date,  
                    dStr = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();  

                selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                self.fun && self.fun(dStr);  
            }, function(e) {  

            }, {  
                title: "请选择日期",  
                date: dDate,  
                minDate: minDate,  
                maxDate: maxDate  
            });  
            return self;  
        },  
        setTime: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultTime = selfEle.getAttribute("data-defaultTime")?selfEle.getAttribute("data-defaultTime").split(":"):null,  
                dTime = new Date();  

            attrDefaultTime?dTime.setHours(attrDefaultTime[0], attrDefaultTime[1]):dTime.setHours(12, 0);  
            plus.nativeUI.pickTime(function(e) {  
                var d = e.date,  
                    dStr = d.getHours() + ":" + d.getMinutes();  

                selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                self.fun && self.fun(dStr);  
            }, function(e) {  

            }, {  
                title: "请选择时间",  
                is24Hour: true,  
                time: dTime  
            });  
            return self;  
        },  
        setDateStr: function(str) {  
            if(typeof str === 'string') {  
                var returnAry = str.split("-").map(function(item, index) {  
                    if(index == 1) {  
                        return +item - 1;  
                    } else {  
                        return +item;  
                    }  
                });  
                var dateObj = new Date();  
                dateObj.setFullYear(returnAry[0], returnAry[1], returnAry[2]);  
                return dateObj;  
            } else {  
                throw new Error('传入的参数不是字符串类型!');  
            }  
        },  
        setDateObj: function(dateAry){  
            var d = new Date();  
                d.setFullYear(dateAry[0],dateAry[1],dateAry[2]);  
            return d;  
        }  
    });  

    $.fn.getDateInfo = function() {  
        this.each(function(i, item) {  
            if(item.GetDateInfo) {  
                return false;  
            } else {  
                item.getDateInfo = new GetDateInfo(item);  
                return true;  
            }  
        });  
    };  
})(mui);

前台代码

<!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="css/mui.min.css" rel="stylesheet" />  
        <script type="text/javascript" charset="utf-8">  
            mui.init();  
        </script>  
        <style type="text/css">  
            #test2 {  
                margin: 20px auto;  
                width: 300px;  
                background-color: #007AFF;  
                padding: 10px;  
                color: #fff;  
                margin-bottom: 15px;  
                border-radius: 4px;  
                text-align: center;  
            }  
            input {  
-webkit-user-select: auto !important;  
}  
        </style>  
    </head>  

    <body>  
        <form class="mui-input-group">  
            <span style="display: block;text-align: center;line-height: 40px;color:#0062CC;background-color: #f7f7f7;;">本插件只在app中有效</span>  
            <div class="mui-input-row">  
                <label>无data参数</label>  
                <input type="text" class="mui-input-clear " placeholder="无data参数">  
            </div>  
            <div class="mui-input-row">  
                <label>选择日期</label>  
                <input type="text" data-dateType="date" class="mui-input-clear" placeholder="选择日期">  
            </div>  
            <div class="mui-input-row">  
                <label>选择时间</label>  
                <input type="text" data-dateType="time" class="mui-input-clear" placeholder="选择时间">  
            </div>  
            <div class="mui-input-row">  
                <label>日期默认值</label>  
                <input type="text" data-defaultDate="2016-11-11" class="mui-input-clear" placeholder="日期默认值">  
            </div>  
            <div class="mui-input-row">  
                <label style="width: 60%;">日期默认、最大最小值</label>  
                <input class="mui-input-clear" data-defaultDate="2016-11-11" data-minDate="2016-11-2" data-maxDate="2016-11-28" placeholder="日期默认、最大最小值" style="width:40%" type="text">  
            </div>  
            <div class="mui-input-row">  
                <label style="width: 50%;">dateTime类型</label>  
                <input class="mui-input-clear" data-dateType="dateTime" data-defaultDate="2016-11-11" data-minDate="2016-11-2" data-maxDate="2016-11-28" data-defaultTime="18:22" placeholder="dateTime类型" style="width:50%" type="text">  
            </div>  
            <div class="mui-input-row">  
                <label>时间默认,</label>  
                <input class="mui-input-clear" data-dateType="time" data-defaultTime="16:32" placeholder="时间默认" type="text">  
            </div>  

            <div id="test2" data-dateType="time">选择时间,动态设置,支持任何参数设置</div>  
            <p class="mui-text-center">更多的组合效果等你来发掘!</p>  
            <script src="js/getDate.js" type="text/javascript" charset="utf-8"></script>  
            <script type="text/javascript">  
                mui.plusReady(function() {  
                    //第一种方法调用,可以为N个元素绑定日期选择  
                    mui("input").getDateInfo();  
                    //第二种方法,可以设置回调函数,第一个返回值为日期字符串,第二个是返回当前的element  

                    var test = new mui.getDateInfo(document.getElementById("test2"), function(d, el) {  
                        //切换状态  
                        var state = el.getAttribute("data-dateType") == "time" ? "date" : "time";  
                        alert("选择的日期为:" + d + "\n我的状态变成了:" + state + "\n在单击下我试试看");  
                        //设置状态  
                        el.setAttribute("data-dateType", state);  
                    });  
                });  
            </script>  
        </form>  
    </body>  

</html>

2016-11-25日更新日志
·增加了新的data-dateType类型 "dateTime"
支持可以同时选择日期和时间,各项设置参数都通用

下面是修改后的js源码

(function($) {  
    var GetDateInfo = $.getDateInfo = $.Class.extend({  
        init: function(element, fun) {  
            var self = this;  
            if(element.nodeType) {  
                self.ele = element;  
                fun && (self.fun = fun);  
                self.EventInit();  
            } else {  
                throw new Error('传入的参数不是Element类型!');  
            }  
            return self;  
        },  
        //绑定事件  
        EventInit: function() {  
            var self = this,  
                selfEle = this.ele,  
                isBindingEvent = selfEle.hasAttribute("data-getDate-event"); //是否绑定点击事件  
            !isBindingEvent && selfEle.addEventListener("tap", function() {  
                self.getDate()  
            }), selfEle.setAttribute("data-getDate-event", true); //绑定点击事件  
            !selfEle.hasAttribute("readonly") && selfEle.tagName == 'INPUT' && selfEle.setAttribute("readonly", "readonly"); //如果是INPUT添加禁用状态  
            return self;  
        },  

        /*为了不犯和官方numbox插件不能动态设置最大值和最小值的错误,本插件采用的都是实时获取attr的值*/  
        getDate: function() {  
            var self = this,  
                selfEle = self.ele,  
                attrDateType = self.dateType = selfEle.getAttribute("data-dateType") || "date";  
                attrDateType == "date" && self.setDate();  
                attrDateType == "time" && self.setTime();  
                attrDateType == "dateTime" && self.setDateTime();  
            return self;  
        },  
        setDate: function(fn) {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultDate = selfEle.getAttribute("data-defaultDate"), //获取attr设置的当前日期  
                dDate = new Date(), //当前日期对象  
                activeDate = [dDate.getFullYear(), dDate.getMonth(), dDate.getDate()], //获取当前日期  
                attrMinDate = selfEle.getAttribute("data-minDate"), //获取最小日期  
                attrMaxDate = selfEle.getAttribute("data-maxDate"), //获取最大日期  
                minDate, maxDate; //最大值、最大值对象  

            /*设置默认日期*/  
            attrDefaultDate ? dDate = self.setDateStr(attrDefaultDate) : dDate.setFullYear(activeDate[0], activeDate[1], activeDate[2]);  
            /*设置最小日期*/  
            attrMinDate && (minDate = attrMinDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMinDate));  
            /*设置最大日期*/  
            attrMaxDate && (maxDate = attrMaxDate=="active"?self.setDateObj(activeDate):self.setDateStr(attrMaxDate));  

            plus && plus.nativeUI.pickDate(function(e) {  
                var d = e.date,  
                    dStr = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();  

                if(self.dateType == 'dateTime'){  
                    fn && fn(dStr);  
                }else{  
                    selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                    self.fun && self.fun(dStr);  
                }  
            }, function(e) {  

            }, {  
                title: "请选择日期",  
                date: dDate,  
                minDate: minDate,  
                maxDate: maxDate  
            });  
        },  
        setTime: function(fn) {  
            var self = this,  
                selfEle = self.ele,  
                attrDefaultTime = selfEle.getAttribute("data-defaultTime")?selfEle.getAttribute("data-defaultTime").split(":"):null,  
                dTime = new Date();  

            attrDefaultTime?dTime.setHours(attrDefaultTime[0], attrDefaultTime[1]):dTime.setHours(12, 0);  
            plus.nativeUI.pickTime(function(e) {  
                var d = e.date,  
                    dStr = d.getHours() + ":" + d.getMinutes();  

                if(self.dateType == 'dateTime'){  
                    fn && fn(dStr);  
                }else{  
                    selfEle.tagName == 'INPUT' && (selfEle.value = dStr);  
                    self.fun && self.fun(dStr);  
                }  
            }, function(e) {  

            }, {  
                title: "请选择时间",  
                is24Hour: true,  
                time: dTime  
            });  
            return self;  
        },  
        setDateTime:function(){  
            var self = this,  
                selfEle = self.ele,  
                returnDateStr = '';  
            self.setDate(function(str){  
                returnDateStr = str;  
                self.setTime(function(str){  
                    returnDateStr +=' '+str;  
                    selfEle.tagName == 'INPUT' && (selfEle.value = returnDateStr);  
                    self.fun && self.fun(returnDateStr);  
                });  
            })  
        },  
        setDateStr: function(str) {  
            if(typeof str === 'string') {  
                var returnAry = str.split("-").map(function(item, index) {  
                    if(index == 1) {  
                        return +item - 1;  
                    } else {  
                        return +item;  
                    }  
                });  
                var dateObj = new Date();  
                dateObj.setFullYear(returnAry[0], returnAry[1], returnAry[2]);  
                return dateObj;  
            } else {  
                throw new Error('传入的参数不是字符串类型!');  
            }  
        },  
        setDateObj: function(dateAry){  
            var d = new Date();  
                d.setFullYear(dateAry[0],dateAry[1],dateAry[2]);  
            return d;  
        }  
    });  

    $.fn.getDateInfo = function() {  
        this.each(function(i, item) {  
            if(item.GetDateInfo) {  
                return false;  
            } else {  
                item.getDateInfo = new GetDateInfo(item);  
                return true;  
            }  
        });  
    };  
})(mui);
收起阅读 »