最近在学前端框架amazeui,之前用其中的CSS样式搭建了一个伪360网页,学会了点布局的东西,但是始终觉得有点无聊。所以这几天就开始研究jquery代码了。
对于我这样一个初学者来说,有很多东西都只能用懵逼来形容,比如我看到这么一段代码(复制自amazeui):
var checkin = $myStart2.datepicker({ onRender: function(date, viewMode) { // 默认 days 视图,与当前日期比较 var viewDate = nowDay; switch (viewMode) { // moths 视图,与当前月份比较 case 1: viewDate = nowMoth; break; // years 视图,与当前年份比较 case 2: viewDate = nowYear; break; } return date.valueOf() < viewDate ? 'am-disabled' : ''; } }).on('changeDate.datepicker.amui', function(ev) { if (ev.date.valueOf() > checkout.date.valueOf()) { var newDate = new Date(ev.date) newDate.setDate(newDate.getDate() + 1); checkout.setValue(newDate); } checkin.close(); $('#my-end-2')[0].focus(); }).data('amui.datepicker');
看这里面的写法,简单的来说就是:
var checkin = $mystart2.datapicker().on().data();
我一开始是以类调用方法来理解的,即datapicker()里面包含了on()这个方法,on()里面包含了data()这个方法。。。
后来想了一下,不太对呀,on()是一个监听事件,应该是对任意一个控件就可以使用的,哪来那么复杂的继承什么的。。。
那这莫非是 -- 同时调用多个方法?好吧,我把代码改了一下,效果是一样的:
datepicker1 = $myStart2.datepicker({ //设置日期 // datepicker1生成了一份日历 onRender: function(date, viewMode) { // onRender是一个方法,其在日历生成后触发,用以渲染 // 传递所设定的日期,以及viewMode -- 0,1,2分别表示日月年 // 默认 days 视图,与当前日期比较 var viewDate = nowDay; switch (viewMode) { // moths 视图,与当前月份比较 case 1: viewDate = nowMoth; break; // years 视图,与当前年份比较 case 2: viewDate = nowYear; break; } return date.valueOf() < viewDate ? 'am-disabled' : ''; // 对每一个日期都作判断,设定其状态是disable或者able } }) datepicker1.on('changeDate.datepicker.amui', function(ev) { /*设置日期结束赋值后的动作*/ if (ev.date.valueOf() > checkout.date.valueOf()) { var newDate = new Date(ev.date) newDate.setDate(newDate.getDate() + 1); checkout.setValue(newDate); /*禁用日期必须比设置日期多一天*/ } checkin.close(); $('#my-end-2')[0].focus(); /*聚焦到禁用日期上*/ }) var checkin = datepicker1.data('amui.datepicker'); // 所设置的具体日期
也就是说,第一段代码干了三件事情:
1. 初始化了日历datapicker();
2. 用了onRender来渲染了datapicker;
3. 把日历中选中的具体日期赋给了checkin。
也就是说,这三个方法,其实只是写在一起而已,没有什么血缘关系。。JS代码原来可以这么任性- -,好吧我一个初学者确实水平不够。
然后我还有第二个问题。。。。这个叫做datapicker的类中,写法是这样的:
XX.datapicker({ onRender: function(data, viewMode){ ........ return XX; } })
这种写法好猎奇,仔细一看的话会发现,如果onRender是datapicker中的一个方法,那么不应该写成:datapicker.onRender(data, viewMode)之类的吗?
后来我去看了一下jQuery UI关于datapicker的描述,发现里面有一些方法是这样的:
onClose : function(dateText, inst) 当日期面板关闭后触发此事件(无论是否有选择日期),参数为选择的日期和当前日期插件的实例。 初始:$('.selector').datepicker({ onClose: function(dateText, inst) { ... } });
原来如此,也就是说,上面的onRender也是一个触发事件,虽然AMUI官方没有讲,我的理解就是,当日历初始化后出发onRender事件,它会把日历上所有的日期都作为参数传递给function(),然后对每个日期进行判断,如果是禁止日期,则返回值“am-disabled”,从而将该日期变成不可选择,否则返回空,即该日期可以选择,这样就可以实现对部分日期的禁用。
至于这个返回值是怎么作用到datapicker上的,我现在也还没搞懂的说。。。。
另外还有关于绑定时间on('event', function(variable))这种jquery中最经典的用法,举个amazeui中的例子:
$('#my-start').datepicker().on('changeDate.datepicker.amui', function(event) { /*'changeDate.datepicker.amui'触发返回event参数,内含date成员可提取日期信息*/ if (event.date.valueOf() > endDate.valueOf()) { $alert.find('p').text('开始日期应小于结束日期!').end().show(); } else { $alert.hide(); startDate = new Date(event.date); $('#my-startDate').text($('#my-start').data('date')); /*把日历控件选择的时间赋值到text中显示*/ } $(this).datepicker('close'); /*日期选择完后关闭日历控件*/ });
注释里面已经说明了,当日期改变时,这段代码就会被触发,然后会把时间参数,即event传递给function,这样就可以获取到事件发生时的相关信息。
今天还看了一下所谓的类创建方法(参考了http://www.cnblogs.com/yjf512/archive/2011/06/03/2071914.html)
function People(name) { this.name=name; //对象方法 this.Introduce=function(){ alert("My name is "+this.name); } } //类方法 People.Run=function(){ alert("I can run"); } //原型方法 People.prototype = { IntroduceChinese :function () { /*增加IntroduceChinese这个方法*/ /* prototype本质上是对类的克隆,但是不会克隆同名函数 若需要调用其克隆母体的同名函数,则需要实例化类后,用call函数来调用*/ alert("我的名字是" + this.name); }, IntroduceDirtyWord: function(){ alert("在下坂本,有何贵干!"); } } //测试 var p1=new People("Windking"); p1.Introduce(); People.Run(); p1.IntroduceChinese(); p1.IntroduceDirtyWord();
这段代码其实说了很多问题:
1. 类方法与对象方法。如Run()是类方法,而IntroduceChinese()是对象方法。
2. prototype的用法,prototype返回的是对象原型类型的引用,也就是说 A.Prototype = new B() 是把B中的所有方法和属性都克隆给了A。在代码例子中,我们使用的是A.Prototype = {method1:function(){}, method2:function(){}}这样的语法,其实也就拓展了A的方法,因此People的实例p1中拥有了通过prototype定义的方法。