最近在學前端框架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定義的方法。