在項目中,使用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
將上面「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) } },