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
This commit is contained in:
Adam Shaw 2010-02-19 23:11:44 -08:00
parent 987d029ba0
commit 9bb6d15fe3
2 changed files with 28 additions and 22 deletions

View file

@ -75,6 +75,7 @@ function Agenda(element, options, methods) {
colCnt, colCnt,
axisWidth, colWidth, slotHeight, axisWidth, colWidth, slotHeight,
viewWidth, viewHeight, viewWidth, viewHeight,
savedScrollTop,
cachedEvents=[], cachedEvents=[],
daySegmentContainer, daySegmentContainer,
slotSegmentContainer, slotSegmentContainer,
@ -95,7 +96,12 @@ function Agenda(element, options, methods) {
clearEvents: clearEvents, clearEvents: clearEvents,
setHeight: setHeight, setHeight: setHeight,
setWidth: setWidth, setWidth: setWidth,
shown: resetScroll, beforeHide: function() {
savedScrollTop = body.scrollTop();
},
afterShow: function() {
body.scrollTop(savedScrollTop);
},
defaultEventEnd: function(event) { defaultEventEnd: function(event) {
var start = cloneDate(event.start); var start = cloneDate(event.start);
if (event.allDay) { if (event.allDay) {
@ -265,19 +271,16 @@ function Agenda(element, options, methods) {
var d0 = zeroDate(), var d0 = zeroDate(),
scrollDate = cloneDate(d0); scrollDate = cloneDate(d0);
scrollDate.setHours(options.firstHour); scrollDate.setHours(options.firstHour);
var go = function() { var top = timePosition(d0, scrollDate) + 1, // +1 for the border
body.scrollTop(timePosition(d0, scrollDate) + 1); // +1 for the border scroll = function() {
// TODO: +1 doesn't apply when firstHour=0 body.scrollTop(top);
} };
//if ($.browser.opera) { scroll();
setTimeout(go, 0); // opera 10 (and earlier?) needs this setTimeout(scroll, 0); // overrides any previous scroll state made by the browser
//}else{
// go();
//}
} }
function setHeight(height, dontResetScroll) { function setHeight(height, dateChanged) {
viewHeight = height; viewHeight = height;
slotTopCache = {}; slotTopCache = {};
@ -290,7 +293,7 @@ function Agenda(element, options, methods) {
height: height height: height
}); });
if (!dontResetScroll) { if (dateChanged) {
resetScroll(); resetScroll();
} }
} }
@ -456,7 +459,7 @@ function Agenda(element, options, methods) {
bindDaySegHandlers, bindDaySegHandlers,
modifiedEventId modifiedEventId
); );
setHeight(viewHeight, true); // might have pushed the body down, so resize setHeight(viewHeight); // might have pushed the body down, so resize
} }
} }

View file

@ -192,20 +192,20 @@ $.fn.fullCalendar = function(options) {
newViewElement; newViewElement;
if (oldView) { 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) { if (oldView.eventsChanged) {
eventsDirty(); eventsDirty();
oldView.eventDirty = oldView.eventsChanged = false; 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'); content.css('overflow', 'hidden');
oldView.element.hide(); oldView.element.hide();
} }
if (viewInstances[v]) { if (viewInstances[v]) {
(view = viewInstances[v]).element.show(); (view = viewInstances[v]).element.show();
if (view.shown) {
view.shown();
}
}else{ }else{
view = viewInstances[v] = $.fullCalendar.views[v]( view = viewInstances[v] = $.fullCalendar.views[v](
newViewElement = $("<div class='fc-view fc-view-" + v + "' style='position:absolute'/>").appendTo(content), newViewElement = $("<div class='fc-view fc-view-" + v + "' style='position:absolute'/>").appendTo(content),
@ -225,9 +225,12 @@ $.fn.fullCalendar = function(options) {
newViewElement.css('position', 'relative'); newViewElement.css('position', 'relative');
} }
if (oldView) { if (oldView) {
content.css('overflow', ''); // needs to be first content.css('overflow', ''); // needs to be called before setting min-height
setMinHeight(content, 0); setMinHeight(content, 0);
} }
if (!newViewElement && view.afterShow) {
view.afterShow(); // called after setting min-height/overflow, so in final scroll state (for Opera)
}
ignoreWindowResize--; ignoreWindowResize--;
} }
@ -239,7 +242,7 @@ $.fn.fullCalendar = function(options) {
if (!view.start || inc || date < view.start || date >= view.end) { if (!view.start || inc || date < view.start || date >= view.end) {
view.render(date, inc || 0); // responsible for clearing events view.render(date, inc || 0); // responsible for clearing events
setSize(); setSize(true);
if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) { if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) {
fetchEvents(function(events) { fetchEvents(function(events) {
ignoreWindowResize++; ignoreWindowResize++;
@ -742,10 +745,10 @@ $.fn.fullCalendar = function(options) {
} }
function setSize() { function setSize(dateChanged) {
ignoreWindowResize++; ignoreWindowResize++;
view.setHeight(suggestedViewHeight); view.setHeight(suggestedViewHeight, dateChanged);
view.setWidth(content.width()); view.setWidth(content.width(), dateChanged);
ignoreWindowResize--; ignoreWindowResize--;
} }