From 9bb6d15fe374062024497b7476d968b26ae5a552 Mon Sep 17 00:00:00 2001 From: Adam Shaw Date: Fri, 19 Feb 2010 23:11:44 -0800 Subject: [PATCH] more enhancements for scrolling in agenda view - less flicker when initially switching to agenda view - when switching back to agenda view, maintains scroll position - when window is resized, maintains scroll position - fixes for Opera --- src/agenda.js | 29 ++++++++++++++++------------- src/main.js | 21 ++++++++++++--------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/agenda.js b/src/agenda.js index ddfb2b3..ce06b05 100644 --- a/src/agenda.js +++ b/src/agenda.js @@ -75,6 +75,7 @@ function Agenda(element, options, methods) { colCnt, axisWidth, colWidth, slotHeight, viewWidth, viewHeight, + savedScrollTop, cachedEvents=[], daySegmentContainer, slotSegmentContainer, @@ -95,7 +96,12 @@ function Agenda(element, options, methods) { clearEvents: clearEvents, setHeight: setHeight, setWidth: setWidth, - shown: resetScroll, + beforeHide: function() { + savedScrollTop = body.scrollTop(); + }, + afterShow: function() { + body.scrollTop(savedScrollTop); + }, defaultEventEnd: function(event) { var start = cloneDate(event.start); if (event.allDay) { @@ -265,19 +271,16 @@ function Agenda(element, options, methods) { var d0 = zeroDate(), scrollDate = cloneDate(d0); scrollDate.setHours(options.firstHour); - var go = function() { - body.scrollTop(timePosition(d0, scrollDate) + 1); // +1 for the border - // TODO: +1 doesn't apply when firstHour=0 - } - //if ($.browser.opera) { - setTimeout(go, 0); // opera 10 (and earlier?) needs this - //}else{ - // go(); - //} + var top = timePosition(d0, scrollDate) + 1, // +1 for the border + scroll = function() { + body.scrollTop(top); + }; + scroll(); + setTimeout(scroll, 0); // overrides any previous scroll state made by the browser } - function setHeight(height, dontResetScroll) { + function setHeight(height, dateChanged) { viewHeight = height; slotTopCache = {}; @@ -290,7 +293,7 @@ function Agenda(element, options, methods) { height: height }); - if (!dontResetScroll) { + if (dateChanged) { resetScroll(); } } @@ -456,7 +459,7 @@ function Agenda(element, options, methods) { bindDaySegHandlers, modifiedEventId ); - setHeight(viewHeight, true); // might have pushed the body down, so resize + setHeight(viewHeight); // might have pushed the body down, so resize } } diff --git a/src/main.js b/src/main.js index ab02215..9c8d927 100644 --- a/src/main.js +++ b/src/main.js @@ -192,20 +192,20 @@ $.fn.fullCalendar = function(options) { newViewElement; if (oldView) { + if (oldView.beforeHide) { + oldView.beforeHide(); // called before changing min-height/overflow. if called after, scroll state is reset (in Opera) + } if (oldView.eventsChanged) { eventsDirty(); oldView.eventDirty = oldView.eventsChanged = false; } - setMinHeight(content, content.height()); // needs to be first + setMinHeight(content, content.height()); // needs to be called before setting overflow content.css('overflow', 'hidden'); oldView.element.hide(); } if (viewInstances[v]) { (view = viewInstances[v]).element.show(); - if (view.shown) { - view.shown(); - } }else{ view = viewInstances[v] = $.fullCalendar.views[v]( newViewElement = $("
").appendTo(content), @@ -225,9 +225,12 @@ $.fn.fullCalendar = function(options) { newViewElement.css('position', 'relative'); } if (oldView) { - content.css('overflow', ''); // needs to be first + content.css('overflow', ''); // needs to be called before setting min-height setMinHeight(content, 0); } + if (!newViewElement && view.afterShow) { + view.afterShow(); // called after setting min-height/overflow, so in final scroll state (for Opera) + } ignoreWindowResize--; } @@ -239,7 +242,7 @@ $.fn.fullCalendar = function(options) { if (!view.start || inc || date < view.start || date >= view.end) { view.render(date, inc || 0); // responsible for clearing events - setSize(); + setSize(true); if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) { fetchEvents(function(events) { ignoreWindowResize++; @@ -742,10 +745,10 @@ $.fn.fullCalendar = function(options) { } - function setSize() { + function setSize(dateChanged) { ignoreWindowResize++; - view.setHeight(suggestedViewHeight); - view.setWidth(content.width()); + view.setHeight(suggestedViewHeight, dateChanged); + view.setWidth(content.width(), dateChanged); ignoreWindowResize--; }