最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fullcalendar v2: How to maintain the same scroll time when navigating weeks? - Stack Overflow

programmeradmin4浏览0评论

On Fullcalendar 2, when I navigate between weeks, I'd like to maintain the same time ranges in the vertical scroll. For example, in the below images, I am initially looking at times from 12am-3pm. But when I press the next arrow to go to the next week, it resets at 8am.

I know that I can change the default starting time with

scrollTime: "08:00:00",

but how do I make it so that the vertical time range is "fixed" to what I am on?

On Fullcalendar 2, when I navigate between weeks, I'd like to maintain the same time ranges in the vertical scroll. For example, in the below images, I am initially looking at times from 12am-3pm. But when I press the next arrow to go to the next week, it resets at 8am.

I know that I can change the default starting time with

scrollTime: "08:00:00",

but how do I make it so that the vertical time range is "fixed" to what I am on?

Share Improve this question asked Oct 20, 2014 at 3:19 kibaekrkibaekr 1,3491 gold badge22 silver badges38 bronze badges 3
  • I'm getting the scroll position but I can't seem to set it (fullcalendar seems to be doing stuff). Maybe you can solve it from here: jsfiddle/3E8nk/568 – Richard Löwenström Commented Oct 20, 2014 at 6:19
  • 1 It seems that you need to use minTime. – Luís Cruz Commented Oct 20, 2014 at 11:31
  • @milz I think that is just if I don't want to display earlier times at all. What I want is: I want all the times to be there, but just not to reset to the scrollTime when I press the next arrows. So just stay on the same time ranges that I was on prior to pressing the navigation arrows – kibaekr Commented Oct 21, 2014 at 1:08
Add a ment  | 

8 Answers 8

Reset to default 4

Unfortunately this is not build-in functionality. There is a workaround but you will always have a little bit of flickering when you go to the previous/next week.

var scroll = -1,
    viewNames = ['agendaWeek', 'agendaDay'];

$('#calendar').fullCalendar({
    //...
    eventAfterAllRender: function(view) {
        if(scroll > -1 && viewNames.indexOf(view.name) !== -1)
            //Use a setTimeout hack here because the scrollTime will be set after eventAfterAllRender is processed.
            setTimeout(function(){                
                document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop = scroll;
            }, 0);
    },
    viewDestroy: function(view) {
        if(viewNames.indexOf(view.name) !== -1)
            scroll = document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop;
    }
    //...
});

jsfiddle

This code will work for FullCalendar v2. It assumes that the scrolling div is the parent of the parent of the .fc-agenda-slots div.

Working Code patible with fullcalendar 2.6.1

I started this code from the post below (A1rPun).

Working JSFiddle

var scroll = -1;

$('#calendar').fullCalendar({

    // init calendar
    header: {left: 'today prev,next, refresh title', 
    right: 'agendaDay,agendaWeek'},
    allDaySlot: false,
    defaultView: 'agendaDay',


    // when all the events are rendered, scroll to the previous saved scroll position
    eventAfterAllRender: function(view) {
        if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek'))
            setTimeout(function(){
            document.querySelector('.fc-scroller').scrollTop = scroll;
        },0);
    },

    // when view is destroyed, we keep the scroll position in a variable
    viewDestroy: function(view) {
        if(view.name=='agendaDay' || view.name=='agendaWeek')
            scroll = document.querySelector('.fc-scroller').scrollTop;
    }

}); // end calendar

This solution is working in 'agendaDay', and 'agendaWeek' views. It's also working when you switch between them.

I don't think it is very pretty because you need to wait until after all the events are rendered. The more events you have on your calendar, the more time the scroll will take..

A good solution would be to use the

Fullcalendar option scrollTime

You can set it in viewRender like this. That will have the effect to make the calendar scroll to this time.

viewRender: function(view, element){
    view.options.scrollTime = '09:00:00';
}

Maybe there is a way to convert the scroll value into time and then render it to the calendar.

EDIT 1

I figured out that is way much better to use the viewRender callback, instead of the eventAfterAllRender callback to set the scroll position.

Here is the JSFiddle

viewRender: function(view, element){

        if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek')){
                    setTimeout(function(){
                    document.querySelector('.fc-scroller').scrollTop = scroll;
                },0);

            }
        },

It's allowing to switch between other wiews (month, basicWeek...) and keep saving the scroll. And it's a bit faster

What I have is:

var height =  $(window).scrollTop();
console.log("current height " + height);

$('#calendar').fullCalendar(  'removeEvents');
$('#calendar').fullCalendar(  'addEventSource', e);
$('#calendar').fullCalendar(  'addEventSource', holiday);
$('#calendar').fullCalendar(  'refetchEvents');

window.scrollTo(0,height);
console.log("scroll to " + height);

and it works for me

Here you can set basic configuration.

scrollTime: '08:00:00',
minTime: '00:00:00', // Set your min time
maxTime: '24:00:00', // Set your max time

yes, main thing is 'height' parameter should not be there in calendar configuration.

Remove below parameter

 height: 'auto'

While I would like to see this as build-in function, this is the fastest and at the same time less verbose solution I found:

viewDestroy: function (view) {
    if (view.name=='agendaDay' || view.name=='agendaWeek') {
        var scrollEl = document.querySelector('.fc-scroller');
        var scrollFraction = scrollEl.scrollTop / scrollEl.scrollHeight;
        this.scrollTime = moment().startOf('day').add(3600 * 24 * scrollFraction, 's').format('HH:mm:00');
        view.options.scrollTime = this.scrollTime;
    }
}

Notice that this assumes the scroll range is 12AM-12AM. If you limit your visible area, you should adapt the day duration as well.

You can try it out: JSFiddle

give a unique class to event object. add this code in after event render method. it will scroll to that specific event

 $('.fc-scroller').animate({
            scrollTop: $('write here unique class of event').position().top
          });

To avoid any scroll "flicking", I did this this way (in fullCalendar 2.9.1) :

viewDestroy: function( aView ) {

    // At first view date change, get height of an hour
    if( !lineHeight )
        lineHeight = $('#calendar').find( "tr.fc-minor" ).height() * 2;

    // then convert current scroll to hour decimal
    var lScrollCurrHour = Math.max( ($('#calendar').find( ".fc-scroller" )[0].scrollTop - 1) / lineHeight, 0 );

    // finally, use moment() to convert to a formatted date
    aView.options.scrollTime = moment().startOf('day')
      .add(lScrollCurrHour, "hours").format("HH:mm:ss");
}

It will keep separated the scroll for week and days agendas

Hope it helps :o)

you could use this to make the scroll time as your desired time.

customButtons:{ 
     PreviousButton: { 
         text: 'Prev', 
         icon: 'left-single-arrow',                     
         click: function() {                                                             
              $('#calendar').fullCalendar('prev');                                                                                                                                                                                  
              $("#calendar").fullCalendar( 'scrollTime',"08:00:00" );
         }                                                                    
     }
}`

The method I specified here is only for previous button. Likewise we can have custom button for all the default buttons in full calendar and we can add this method to scroll the time whenever needed. i hope this would help.

发布评论

评论列表(0)

  1. 暂无评论