UI Tabs: fixed tabs select causing page to jump bug, removed cruft form former history integration which will work differently anyway

This commit is contained in:
Klaus Hartl 2008-11-05 10:59:55 +00:00
parent e4d0e3e2e3
commit 7e11903beb

View File

@ -95,23 +95,13 @@ $.widget("ui.tabs", {
this.$tabs.each(function(i, a) { this.$tabs.each(function(i, a) {
if (a.hash == location.hash) { if (a.hash == location.hash) {
o.selected = i; o.selected = i;
// prevent page scroll to fragment
if ($.browser.msie || $.browser.opera) {
var $toShow = $(this._sanitizeSelector(location.hash)), toShowId = $toShow.attr('id');
$toShow.attr('id', '');
setTimeout(function() {
$toShow.attr('id', toShowId); // restore id
}, 500);
}
scrollTo(0, 0);
return false; // break return false; // break
} }
}); });
} }
else if (o.cookie) { else if (o.cookie) {
var index = parseInt(self._cookie(), 10); var index = parseInt(self._cookie(), 10);
if (index && self.$tabs[index]) if (index && self.$tabs[index]) o.selected = index;
o.selected = index;
} }
else if (self.$lis.filter('.' + o.selectedClass).length) else if (self.$lis.filter('.' + o.selectedClass).length)
o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] ); o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] );
@ -132,7 +122,7 @@ $.widget("ui.tabs", {
this.$panels.addClass(o.hideClass); this.$panels.addClass(o.hideClass);
this.$lis.removeClass(o.selectedClass); this.$lis.removeClass(o.selectedClass);
if (o.selected !== null) { if (o.selected !== null) {
this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before this.$panels.eq(o.selected).removeClass(o.hideClass);
var classes = [o.selectedClass]; var classes = [o.selectedClass];
if (o.deselectable) classes.push(o.deselectableClass); if (o.deselectable) classes.push(o.deselectableClass);
this.$lis.eq(o.selected).addClass(classes.join(' ')); this.$lis.eq(o.selected).addClass(classes.join(' '));
@ -147,8 +137,7 @@ $.widget("ui.tabs", {
if ($.data(this.$tabs[o.selected], 'load.tabs')) if ($.data(this.$tabs[o.selected], 'load.tabs'))
this.load(o.selected, onShow); this.load(o.selected, onShow);
// just trigger show event // just trigger show event
else else onShow();
onShow();
} }
// clean up to avoid memory leaks in certain versions of IE 6 // clean up to avoid memory leaks in certain versions of IE 6
@ -163,59 +152,62 @@ $.widget("ui.tabs", {
o.selected = this.$lis.index( this.$lis.filter('.' + o.selectedClass)[0] ); o.selected = this.$lis.index( this.$lis.filter('.' + o.selectedClass)[0] );
// set or update cookie after init and add/remove respectively // set or update cookie after init and add/remove respectively
if (o.cookie) if (o.cookie) this._cookie(o.selected, o.cookie);
this._cookie(o.selected, o.cookie);
// disable tabs // disable tabs
for (var i = 0, li; li = this.$lis[i]; i++) for (var i = 0, li; li = this.$lis[i]; i++)
$(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass); $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);
// reset cache if switching from cached to not cached // reset cache if switching from cached to not cached
if (o.cache === false) if (o.cache === false) this.$tabs.removeData('cache.tabs');
this.$tabs.removeData('cache.tabs');
// set up animations // set up animations
var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal'; var hideFx, showFx;
if (o.fx && o.fx.constructor == Array) if (o.fx) {
hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx; if (o.fx.constructor == Array) {
else hideFx = o.fx[0];
hideFx = showFx = o.fx || baseFx; showFx = o.fx[1];
}
else hideFx = showFx = o.fx;
}
// Reset certain styles left over from animation to // Reset certain styles left over from animation
// maintain print style sheets and prevent IE's // and prevent IE's ClearType bug...
// ClearType bug...
function resetStyle($el, fx) { function resetStyle($el, fx) {
$el.css({ display: '' }); $el.css({ display: '' });
if ($.browser.msie && fx.opacity) if ($.browser.msie && fx.opacity) $el[0].style.removeAttribute('filter');
$el[0].style.filter = '';
} }
// Hide a tab, animation prevents browser scrolling to fragment, // Show a tab...
// $show is optional. var showTab = showFx ?
function hideTab(clicked, $hide, $show) { function(clicked, $show) {
$hide.animate(hideFx, hideFx.duration || baseDuration, function() { // $show.animate(showFx, showFx.duration || 'normal', function() {
$hide.addClass(o.hideClass); $show.removeClass(o.hideClass);
resetStyle($hide, hideFx); resetStyle($show, showFx);
if ($show) showTab(clicked, $show, $hide); self._trigger('show', null, self.ui(clicked, $show[0]));
}); });
} } :
function(clicked, $show) {
// Show a tab, animation prevents browser scrolling to fragment,
// $hide is optional.
function showTab(clicked, $show, $hide) {
if (showFx === baseFx) $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox caused by gap between showing and hiding the tab panels
$show.animate(showFx, showFx.duration || baseDuration, function() {
$show.removeClass(o.hideClass); $show.removeClass(o.hideClass);
resetStyle($show, showFx);
self._trigger('show', null, self.ui(clicked, $show[0])); self._trigger('show', null, self.ui(clicked, $show[0]));
}); };
}
// switch a tab // Hide a tab, $show is optional...
var hideTab = hideFx ?
function(clicked, $hide, $show) {
$hide.animate(hideFx, hideFx.duration || 'normal', function() {
$hide.addClass(o.hideClass);
resetStyle($hide, hideFx);
if ($show) showTab(clicked, $show, $hide);
});
} :
function(clicked, $hide, $show) {
$hide.addClass(o.hideClass);
if ($show) showTab(clicked, $show);
};
// Switch a tab...
function switchTab(clicked, $li, $hide, $show) { function switchTab(clicked, $li, $hide, $show) {
/*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
$.ajaxHistory.update(clicked.hash);
}*/
var classes = [o.selectedClass]; var classes = [o.selectedClass];
if (o.deselectable) classes.push(o.deselectableClass); if (o.deselectable) classes.push(o.deselectableClass);
$li.addClass(classes.join(' ')).siblings().removeClass(classes.join(' ')); $li.addClass(classes.join(' ')).siblings().removeClass(classes.join(' '));
@ -266,24 +258,13 @@ $.widget("ui.tabs", {
} }
} }
if (o.cookie) if (o.cookie) self._cookie(o.selected, o.cookie);
self._cookie(o.selected, o.cookie);
// stop possibly running animations // stop possibly running animations
self.$panels.stop(); self.$panels.stop();
// show new tab // show new tab
if ($show.length) { if ($show.length) {
// prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
/*if ($.browser.msie && o.bookmarkable) {
var showId = this.hash.replace('#', '');
$show.attr('id', '');
setTimeout(function() {
$show.attr('id', showId); // restore id
}, 0);
}*/
var a = this; var a = this;
self.load(self.$tabs.index(this), $hide.length ? self.load(self.$tabs.index(this), $hide.length ?
function() { function() {
@ -294,32 +275,21 @@ $.widget("ui.tabs", {
showTab(a, $show); showTab(a, $show);
} }
); );
// Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
/*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
setTimeout(function() {
scrollTo(scrollX, scrollY);
}, 0);*/
} else } else
throw 'jQuery UI Tabs: Mismatching fragment identifier.'; throw 'jQuery UI Tabs: Mismatching fragment identifier.';
// Prevent IE from keeping other link focussed when using the back button // Prevent IE from keeping other link focussed when using the back button
// and remove dotted border from clicked link. This is controlled in modern // and remove dotted border from clicked link. This is controlled via CSS
// browsers via CSS, also blur removes focus from address bar in Firefox // in modern browsers; blur() removes focus from address bar in Firefox
// which can become a usability and annoying problem with tabsRotate. // which can become a usability and annoying problem with tabs('rotate').
if ($.browser.msie) if ($.browser.msie) this.blur();
this.blur();
//return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
return false; return false;
}); });
// disable click if event is configured to something else // disable click if event is configured to something else
if (o.event != 'click') if (o.event != 'click') this.$tabs.bind('click.tabs', function(){return false;});
this.$tabs.bind('click.tabs', function() { return false; });
}, },
add: function(url, label, index) { add: function(url, label, index) {
@ -438,10 +408,10 @@ $.widget("ui.tabs", {
}; };
var cleanup = function() { var cleanup = function() {
self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass) self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
.each(function() { .each(function() {
if (o.spinner) if (o.spinner)
inner(this).parent().html(inner(this).data('label.tabs')); inner(this).parent().html(inner(this).data('label.tabs'));
}); });
self.xhr = null; self.xhr = null;
}; };
@ -479,10 +449,7 @@ $.widget("ui.tabs", {
cleanup(); cleanup();
} }
$a.addClass(o.loadingClass); $a.addClass(o.loadingClass);
setTimeout(function() { // timeout is again required in IE, "wait" for id being restored self.xhr = $.ajax(ajaxOptions);
self.xhr = $.ajax(ajaxOptions);
}, 0);
}, },
url: function(index, url) { url: function(index, url) {
this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url); this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
@ -590,4 +557,18 @@ $.extend($.ui.tabs.prototype, {
} }
}); });
$.extend($.ui.tabs.prototype, {
equalize: function() {
var heights = this.$panels.map(function() {
return $(this).height();
})
.get()
.sort(function(a, b) {
return b - a;
});
// set all panels to highest height
this.$panels.css('height', heights[0]);
}
});
})(jQuery); })(jQuery);