Skip to content

Commit 7832fd8

Browse files
committed
Datepicker: Avoid flash during render in Firefox. Fixes #5493 - Datepicker: changeYear + yearRange causes flash in Firefox.
Thanks israelrios.
1 parent 53215de commit 7832fd8

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

ui/jquery.ui.datepicker.js

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ $.extend(Datepicker.prototype, {
624624
}
625625
var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
626626
$.datepicker._pos = null;
627+
//to avoid flashes on Firefox
628+
inst.dpDiv.empty();
627629
// determine sizing offscreen
628630
inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
629631
$.datepicker._updateDatepicker(inst);
@@ -638,10 +640,12 @@ $.extend(Datepicker.prototype, {
638640
var duration = $.datepicker._get(inst, 'duration');
639641
var postProcess = function() {
640642
$.datepicker._datepickerShowing = true;
641-
var borders = $.datepicker._getBorders(inst.dpDiv);
642-
inst.dpDiv.find('iframe.ui-datepicker-cover'). // IE6- only
643-
css({left: -borders[0], top: -borders[1],
643+
var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
644+
if( !! cover.length ){
645+
var borders = $.datepicker._getBorders(inst.dpDiv);
646+
cover.css({left: -borders[0], top: -borders[1],
644647
width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
648+
}
645649
};
646650
inst.dpDiv.zIndex($(input).zIndex()+1);
647651
if ($.effects && $.effects[showAnim])
@@ -660,12 +664,12 @@ $.extend(Datepicker.prototype, {
660664
_updateDatepicker: function(inst) {
661665
var self = this;
662666
var borders = $.datepicker._getBorders(inst.dpDiv);
663-
inst.dpDiv.empty().append(this._generateHTML(inst))
664-
.find('iframe.ui-datepicker-cover') // IE6- only
665-
.css({left: -borders[0], top: -borders[1],
666-
width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
667-
.end()
668-
.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
667+
inst.dpDiv.empty().append(this._generateHTML(inst));
668+
var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
669+
if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
670+
cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
671+
}
672+
inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
669673
.bind('mouseout', function(){
670674
$(this).removeClass('ui-state-hover');
671675
if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
@@ -697,6 +701,17 @@ $.extend(Datepicker.prototype, {
697701
if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
698702
inst.input.is(':visible') && !inst.input.is(':disabled'))
699703
inst.input.focus();
704+
// deffered render of the years select (to avoid flashes on Firefox)
705+
if( inst.yearshtml ){
706+
var origyearshtml = inst.yearshtml;
707+
setTimeout(function(){
708+
//assure that inst.yearshtml didn't change.
709+
if( origyearshtml === inst.yearshtml ){
710+
inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
711+
}
712+
origyearshtml = inst.yearshtml = null;
713+
}, 0);
714+
}
700715
},
701716

702717
/* Retrieve the size of left and top borders for an element.
@@ -1548,6 +1563,7 @@ $.extend(Datepicker.prototype, {
15481563
if (!showMonthAfterYear)
15491564
html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : '');
15501565
// year selection
1566+
inst.yearshtml = '';
15511567
if (secondary || !changeYear)
15521568
html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
15531569
else {
@@ -1564,16 +1580,24 @@ $.extend(Datepicker.prototype, {
15641580
var endYear = Math.max(year, determineYear(years[1] || ''));
15651581
year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
15661582
endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1567-
html += '<select class="ui-datepicker-year" ' +
1583+
inst.yearshtml += '<select class="ui-datepicker-year" ' +
15681584
'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
15691585
'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
15701586
'>';
15711587
for (; year <= endYear; year++) {
1572-
html += '<option value="' + year + '"' +
1588+
inst.yearshtml += '<option value="' + year + '"' +
15731589
(year == drawYear ? ' selected="selected"' : '') +
15741590
'>' + year + '</option>';
15751591
}
1576-
html += '</select>';
1592+
inst.yearshtml += '</select>';
1593+
//when showing there is no need for later update
1594+
if( ! $.browser.mozilla ){
1595+
html += inst.yearshtml;
1596+
inst.yearshtml = null;
1597+
} else {
1598+
// will be replaced later with inst.yearshtml
1599+
html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';
1600+
}
15771601
}
15781602
html += this._get(inst, 'yearSuffix');
15791603
if (showMonthAfterYear)

0 commit comments

Comments
 (0)