jQuery UI datepicker選擇日期後,日期層會再次加載

 在項目中,使用jQuery UI的datepicker日期控件時,出現如下問題: 
  一、在IE瀏覽器下,選擇好日期後,datepicker的日期顯示會從新加載; 
  二、在Firefox瀏覽器下,選擇好日期後,datepicker的日期顯示不會從新加載,但是想再次修改日期時,焦點必須離開輸入的日期框後,再點擊進入才能出現datepicker的日期選擇框。 css

百度獲得的答案以下:html


  針對上述出現的問題,我對jQuery UI 1.8.15版本的源碼進行了查看,發現jquery.ui.datepicker是由focus事情來顯示日期選擇層的,經檢查代碼發現_selectDate方法中默認的選擇日期是選擇日期賦值給輸入框後,再從新對輸入框設定focus。這樣在IE瀏覽器下就會出現日期選擇框從新加載了。 

  問題代碼出如今jquery.ui.datepicker.js文件的909到930行,其具體以下: jquery

Javascript代碼  收藏代碼
  1. /* Update the input field with the selected date. */  
  2. _selectDate: function(id, dateStr) {  
  3.     var target = $(id);  
  4.     var inst = this._getInst(target[0]);  
  5.     dateStr = (dateStr != null ? dateStr : this._formatDate(inst));  
  6.     if (inst.input)  
  7.         inst.input.val(dateStr);  
  8.     this._updateAlternate(inst);  
  9.     var onSelect = this._get(inst, 'onSelect');  
  10.     if (onSelect)  
  11.         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback  
  12.     else if (inst.input)  
  13.         inst.input.trigger('change'); // fire the change event  
  14.     if (inst.inline)  
  15.         this._updateDatepicker(inst);  
  16.     else {  
  17.         this._hideDatepicker();  
  18.         this._lastInput = inst.input[0];  
  19.         inst.input.focus(); // restore focus  
  20.         this._lastInput = null;  
  21.     }  
  22. },  



     將上面「inst.input.focus(); // restore focus」的代碼註釋掉後,進行測試。發現上述出現的兩個問題都能解決,所以決定修改jQuery UI的代碼。 

    經過代碼研究發現,上述遇到的問題,應該也能夠經過自定義onSelect方法來實現。只是簡單試了下,效果沒達到,因此就冒險對jQuery UI的代碼進行修改了。 

    項目中引用的jQuery UI是min的js文件,也就是jQuery UI團隊發佈的,通過壓縮後的文件。該文件和源碼存在很大差異。主要區別有: 
    一、源碼文件是分plugin來定義單個js文件的; 
    二、jquery-ui-1.8.15.custom.min.js文件是將全部發布的ui,集成在一個文件裏; 
    三、jquery-ui-1.8.15.custom.min.js文件的代碼通過了壓縮。 

    不過還好,jquery-ui-1.8.15.custom.min.js文件的壓縮主要是針對定義的變量進行的。經datepicker、_selectDate和focus()一路查找下來。終於找到了a.input.focus();這句代碼。將其刪除後,測試後達到了解決效果。 瀏覽器

可是在實踐的時候,出現一些小的出入,我使用的jquery-ui-1.8.11.custom.min.js這個版本中屏蔽瞭如下兩個位置的focus方法,分別解決了上面兩個問題app

  _selectDate: function (a, b) {
            if (d(a)[0]) {
                a = this._getInst(d(a)[0]);
                b = b != null ? b : this._formatDate(a);
                a.input && a.input.val(b);
                this._updateAlternate(a);
                var c = this._get(a, "onSelect");
                if (c)
                    c.apply(a.input ? a.input[0] : null, [b, a]);
                else a.input && a.input.trigger("change");
                if (a.inline)
                    this._updateDatepicker(a);
                else {
                    this._hideDatepicker();
                    this._lastInput = a.input[0];
                    typeof a.input[0] != "object";//&& a.input.focus();
                    this._lastInput = null
                }
            }
        },
 _updateDatepicker: function (a) {
            var b = this,
                c = d.datepicker._getBorders(a.dpDiv);
            a.dpDiv.empty().append(this._generateHTML(a));
            var e = a.dpDiv.find("iframe.ui-datepicker-cover");
            e.length && e.css({ left: -c[0], top: -c[1], width: a.dpDiv.outerWidth(), height: a.dpDiv.outerHeight() });
            a.dpDiv.find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout", function () {
                d(this).removeClass("ui-state-hover");
                this.className.indexOf("ui-datepicker-prev") != -1 && d(this).removeClass("ui-datepicker-prev-hover");
                this.className.indexOf("ui-datepicker-next") != -1 && d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover", function () { 
                    if (!b._isDisabledDatepicker(a.inline ? a.dpDiv.parent()[0] : a.input[0])) {
                        d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
                        d(this).addClass("ui-state-hover");
                        this.className.indexOf("ui-datepicker-prev") != -1 && d(this).addClass("ui-datepicker-prev-hover");
                        this.className.indexOf("ui-datepicker-next") != -1 && d(this).addClass("ui-datepicker-next-hover")
                    }
                }).end().find("." + this._dayOverClass + " a").trigger("mouseover").end();
            c = this._getNumberOfMonths(a);
            e = c[1]; e > 1 ? a.dpDiv.addClass("ui-datepicker-multi-" + e).css("width", 17 * e + "em") : a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
            a.dpDiv[(c[0] != 1 || c[1] != 1 ? "add" : "remove") + "Class"]("ui-datepicker-multi");
            a.dpDiv[(this._get(a, "isRTL") ? "add" : "remove") + "Class"]("ui-datepicker-rtl");
            a == d.datepicker._curInst && d.datepicker._datepickerShowing && a.input && a.input.is(":visible") && !a.input.is(":disabled") &&a.input[0] != document.activeElement ;//&& a.input.focus();
            if (a.yearshtml) { var f = a.yearshtml; setTimeout(function () { f === a.yearshtml && a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml); f = a.yearshtml = null }, 0) }
        },
相關文章
相關標籤/搜索