jQuery UI datepicker选择日期后,日期层会再次加载

 在项目中,使用jQuery UI的datepicker日期控件时,出现以下问题: 
  1、在IE浏览器下,选择好日期后,datepicker的日期显示会重新加载; 
  2、在Firefox浏览器下,选择好日期后,datepicker的日期显示不会重新加载,可是想再次修改日期时,焦点必须离开输入的日期框后,再点击进入才能出现datepicker的日期选择框。 

百度得到的答案如下:


  针对上述出现的问题,我对jQuery UI 1.8.15版本的源码进行了查看,发现jquery.ui.datepicker是由focus事情来显示日期选择层的,经检查代码发现_selectDate方法中默认的选择日期是选择日期赋值给输入框后,再重新对输入框设定focus。这样在IE浏览器下就会出现日期选择框重新加载了。 

  问题代码出现在jquery.ui.datepicker.js文件的909到930行,其具体如下: 

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团队发布的,经过压缩后的文件。该文件和源码存在很大差别。主要区别有: 
    1、源码文件是分plugin来定义单个js文件的; 
    2、jquery-ui-1.8.15.custom.min.js文件是将所有发布的ui,集成在一个文件里; 
    3、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方法,分别解决了上面两个问题

  _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) }
        },

 

posted @ 2016-01-21 11:10  左魅颜  阅读(717)  评论(0编辑  收藏  举报