在项目中,使用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) } },