jQuery 學習筆記(函數調用機制)


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM