You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FullCalendar v3中实现类谷歌日历的年视图

Custom Google Calendar-Style Year View for FullCalendar 3

Hey there! I get it—FullCalendar 3's default year view plugins don't quite match the clean, intuitive feel of Google Calendar's year view. Let's build a custom one that fits your needs, using your existing config as a starting point.

Step 1: Update Your FullCalendar Config

First, we'll extend your existing setup to register a custom year view, add logic to render the year view grid, and map events to the correct dates. Here's the modified code:

$('#calendar').fullCalendar({
  header: {
    left: 'prev,next today',
    center: 'title',
    right: 'year,month,agendaWeek,agendaDay', // Keep the year toggle button
  },
  firstDay: 1,
  eventLimit: true,
  slotMinutes: 5,
  // Register our custom year view
  views: {
    year: {
      type: 'year',
      duration: { years: 1 },
      buttonText: 'Year'
    }
  },
  // Build the year view grid when the view loads
  viewRender: function(view, element) {
    if (view.name === 'year') {
      // Clear default content to build our custom layout
      element.find('.fc-content').empty();
      const currentYear = view.start.year();
      const monthContainers = [];

      // Generate a container for each month
      for (let monthIndex = 0; monthIndex < 12; monthIndex++) {
        const monthStart = moment([currentYear, monthIndex, 1]);
        const monthName = monthStart.format('MMMM');
        
        // Create month wrapper with title and grid
        const monthContainer = $('<div class="fc-year-month"></div>').append(
          `<h3 class="fc-month-title">${monthName}</h3>`,
          `<div class="fc-month-grid"></div>`
        );
        monthContainers.push(monthContainer);

        // Populate the month's date grid
        const grid = monthContainer.find('.fc-month-grid');
        const daysInMonth = monthStart.daysInMonth();
        const firstDayOffset = monthStart.day(); // Matches your firstDay:1 (Monday)

        // Add empty days for the start of the month
        for (let i = 0; i < firstDayOffset; i++) {
          grid.append('<div class="fc-day fc-day-empty"></div>');
        }

        // Add actual date cells
        for (let day = 1; day <= daysInMonth; day++) {
          const date = moment([currentYear, monthIndex, day]);
          const dayElement = $(`<div class="fc-day fc-day-number" data-date="${date.format('YYYY-MM-DD')}">${day}</div>`);
          grid.append(dayElement);
        }
      }

      // Add all month containers to the calendar content area
      element.find('.fc-content').append(monthContainers);
    }
  },
  // Render events into the year view's date cells
  eventRender: function(event, element, view) {
    if (view.name === 'year') {
      const eventDate = moment(event.start).format('YYYY-MM-DD');
      const targetDay = $(`.fc-day[data-date="${eventDate}"]`);

      // Create a compact event label (matching Google Calendar's style)
      const eventElement = $('<div class="fc-year-event"></div>').text(event.title);
      
      // Limit visible events per day to avoid clutter
      if (targetDay.find('.fc-year-event').length < 3) {
        targetDay.append(eventElement);
      } else {
        // Show "more" link if there are extra events
        if (!targetDay.find('.fc-year-more').length) {
          targetDay.append('<div class="fc-year-more">+more</div>');
        }
      }

      // Add click handler to show event details (customize this as needed)
      eventElement.click(function() {
        alert(`Event: ${event.title}\nDate: ${event.start.format('LL')}`);
      });

      // Prevent default FullCalendar event behavior in year view
      return false;
    }
  }
});

Step 2: Add Custom CSS for Google Calendar-Like Styling

To make the layout look polished and similar to Google Calendar, add this CSS:

/* Year view container styling */
.fc-year-month {
  float: left;
  width: 25%; /* 4 columns of months - adjust for your needs */
  padding: 10px;
  box-sizing: border-box;
}

.fc-month-title {
  margin: 0 0 8px 0;
  font-size: 14px;
  font-weight: 600;
  color: #202124;
}

/* Month date grid */
.fc-month-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.fc-day {
  height: 32px;
  font-size: 12px;
  padding: 2px;
  box-sizing: border-box;
  border-radius: 4px;
  position: relative;
}

.fc-day-empty {
  background-color: #f8f9fa;
}

.fc-day-number {
  background-color: #ffffff;
  border: 1px solid #dadce0;
  padding-top: 2px;
}

/* Event styling */
.fc-year-event {
  font-size: 10px;
  padding: 1px 3px;
  margin-top: 2px;
  background-color: #1a73e8; /* Google Calendar blue - customize your color */
  color: #ffffff;
  border-radius: 2px;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.fc-year-more {
  font-size: 10px;
  color: #5f6368;
  margin-top: 2px;
  cursor: pointer;
}

/* Responsive adjustment for smaller screens */
@media (max-width: 768px) {
  .fc-year-month {
    width: 50%; /* Switch to 2 columns on mobile */
  }
}

Key Notes to Customize Further

  • Column Layout: Change the width of .fc-year-month to adjust how many months fit per row (e.g., 33.33% for 3 columns).
  • Event Colors: Swap out the background-color of .fc-year-event to match your brand.
  • Event Details: Replace the alert in the eventElement.click handler with a modal or custom tooltip for a better user experience.
  • Dependencies: Ensure you have jQuery and Moment.js loaded (required for FullCalendar 3).

内容的提问来源于stack exchange,提问作者Akshay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:17:36