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

javascript - How do I change background colorimage based on currently viewed month? - Stack Overflow

programmeradmin2浏览0评论

I am building a calendar using Full calendar. I have a specific background that I want for each month. The color changes according to the current day correctly. If it is currently march 17, it will show the march background.

I cannot figure out how to make the background change whenever I browse to look at future/past months. It stays the same. I want the background to change when I look at a different month.

Thanks in advance! I'm scratching my head at this one!

My code correctly sets the current months background initially.

Today's date with the correct background color

When I browse to another month it doesn't change.

Browsing to new months keeps the same color when it should be changing

If i change my PC's time to another month, the background is different, so that part works.

Image when i change my computer time to a different time

My Current Code:

<script>
  $(document).ready(function() {
    var monthColors = [
            "#FF5733",   // January - Red-Orange
            "#33B5E5",   // February - Blue
            "#A569BD",   // March - Purple
            "#58D68D",   // April - Green
            "#F4D03F",   // May - Yellow
            "#FF8C00",   // June - Orange
            "#4682B4",   // July - Steel Blue
            "#DC143C",   // August - Crimson
            "#20B2AA",   // September - Light Sea Green
            "#FF6347",   // October - Tomato
            "#2E8B57",  // November - Sea Green
            "#B22222"   // December - Fire Brick
        ];       
        function updateBackground(date) {
            var month = date.getMonth(); // Get displayed month
            console.log("Updating background for month:", month + 1); // Debugging log
            $("body").css("background-color", monthColors[month]);
        }

  $('#calendar').fullCalendar(
    {
      header:
      {
        left: '',
        center: 'title'
      },
      events:
      [
        {
          title: 'Marriage',
          start: '2025-03-17',
          color: 'transparent',
          textColor: 'black',
          imageurl: 'birthday.png'
          },
          {
          title: 'Marriage',
          start: '2025-03-19',
          end: '2025-03-20',
          color: '#8E9A75',
          textColor: 'white',
          imageurl: 'birthday.png'
          }
      ],
      eventRender: function(event, eventElement) {
      if (event.imageurl) {
        eventElement.prepend("<img src='" + event.imageurl + "' width='80' height='80' >");
      }  return ['all', event.tags].indexOf($('#event_selector option:selected').val()) >= 0;
      },
      datesSet: function(info) {
        var currentMonth = calendar.getDate().getMonth() + 1;
            console.log("Currently viewed month:", currentMonth);
      },

      
  }); 

  setTimeout(function() {
            updateBackground(new Date());
        }, 100);

});


</script>

I am building a calendar using Full calendar. I have a specific background that I want for each month. The color changes according to the current day correctly. If it is currently march 17, it will show the march background.

I cannot figure out how to make the background change whenever I browse to look at future/past months. It stays the same. I want the background to change when I look at a different month.

Thanks in advance! I'm scratching my head at this one!

My code correctly sets the current months background initially.

Today's date with the correct background color

When I browse to another month it doesn't change.

Browsing to new months keeps the same color when it should be changing

If i change my PC's time to another month, the background is different, so that part works.

Image when i change my computer time to a different time

My Current Code:

<script>
  $(document).ready(function() {
    var monthColors = [
            "#FF5733",   // January - Red-Orange
            "#33B5E5",   // February - Blue
            "#A569BD",   // March - Purple
            "#58D68D",   // April - Green
            "#F4D03F",   // May - Yellow
            "#FF8C00",   // June - Orange
            "#4682B4",   // July - Steel Blue
            "#DC143C",   // August - Crimson
            "#20B2AA",   // September - Light Sea Green
            "#FF6347",   // October - Tomato
            "#2E8B57",  // November - Sea Green
            "#B22222"   // December - Fire Brick
        ];       
        function updateBackground(date) {
            var month = date.getMonth(); // Get displayed month
            console.log("Updating background for month:", month + 1); // Debugging log
            $("body").css("background-color", monthColors[month]);
        }

  $('#calendar').fullCalendar(
    {
      header:
      {
        left: '',
        center: 'title'
      },
      events:
      [
        {
          title: 'Marriage',
          start: '2025-03-17',
          color: 'transparent',
          textColor: 'black',
          imageurl: 'birthday.png'
          },
          {
          title: 'Marriage',
          start: '2025-03-19',
          end: '2025-03-20',
          color: '#8E9A75',
          textColor: 'white',
          imageurl: 'birthday.png'
          }
      ],
      eventRender: function(event, eventElement) {
      if (event.imageurl) {
        eventElement.prepend("<img src='" + event.imageurl + "' width='80' height='80' >");
      }  return ['all', event.tags].indexOf($('#event_selector option:selected').val()) >= 0;
      },
      datesSet: function(info) {
        var currentMonth = calendar.getDate().getMonth() + 1;
            console.log("Currently viewed month:", currentMonth);
      },

      
  }); 

  setTimeout(function() {
            updateBackground(new Date());
        }, 100);

});


</script>
Share Improve this question edited Mar 19 at 8:56 ADyson 62.2k16 gold badges79 silver badges92 bronze badges asked Mar 17 at 22:45 Ryan ShupeRyan Shupe 31 silver badge3 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 4

I could not get your code to work - there were syntax errors (missing {) etc.

Here is a version with the Fullcalendar updated to v6 and using the new syntax to instantiate the FullCalendar

Note that the dataSet function handles the initial render too making the setTimeout redundant so I removed it.

$(document).ready(function() {

  const updateBackground = (date) => {
    const month = date.getMonth();
    // console.log("Updating background for month:", month + 1);
    $("body").css("background-color", monthColors[month]);
  };

  // Initialize FullCalendar
  const calendarEl = document.getElementById('calendar');
  const calendar = new FullCalendar.Calendar(calendarEl, {
    headerToolbar: { // Updated from 'header' to 'headerToolbar'
      left: '',
      center: 'title',
      right: ''
    },
    events: events, // from elswhere on the page or Ajaxed
    eventContent: (arg) => { // Updated from 'eventRender' to 'eventContent'
      const event = arg.event;
      if (event.extendedProps.imageurl) {
        return {
          html: `<img src="${event.extendedProps.imageurl}" width="80" height="80"><br>${event.title}`
        };
      }
      return true; // Default rendering
    },
    datesSet: (info) => {
      const currentMonth = info.view.currentStart.getMonth() + 1;
      // console.log("Currently viewed month:", currentMonth);
      updateBackground(info.view.currentStart); // Update background when view changes - handles the initial view too
    },
  });

  // Render the calendar
  calendar.render();

});
<script src="https://cdnjs.cloudflare/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src='https://cdn.jsdelivr/npm/[email protected]/index.global.min.js'></script>


<div id="calendar"></div>





<script>
  // consts better sourced from elsewhere - ajax for example
  const monthColors = [
    "#FF5733", "#33B5E5", "#A569BD", "#58D68D", "#F4D03F",
    "#FF8C00", "#4682B4", "#DC143C", "#20B2AA", "#FF6347",
    "#2E8B57", "#B22222"
  ];

  const events = [{
      title: 'Birthday',
      start: '2025-03-17',
      color: 'transparent',
      textColor: 'black',
      imageurl: 'https://images.freeimages/image/previews/1db/birthday-quote-png-celebration-5690238.png'
    },
    {
      title: 'Marriage',
      start: '2025-03-19',
      end: '2025-03-20',
      color: '#8E9A75',
      textColor: 'white',
      imageurl: 'https://clipart-library/img/812312.png'
    }
  ];
  </script>

Since we use the new version 6, there is no need for jQuery. I changed the image handling a bit

document.addEventListener('DOMContentLoaded', function() {
  const updateBackground = (date) => {
    const month = date.getMonth();
    document.body.style.backgroundColor = monthColors[month]; // Vanilla JS instead of jQuery
  }

  const calendarEl = document.getElementById('calendar');
  const calendar = new FullCalendar.Calendar(calendarEl, {
    headerToolbar: {
      left: '',
      center: 'title',
      right: ''
    },
    events: events,
    eventContent: (arg) => {
      const event = arg.event;
      if (event.extendedProps.imageurl) {
        const img = document.createElement('img');
        img.src = event.extendedProps.imageurl;
        img.width = 80;
        img.height = 80;
        const title = document.createTextNode(event.title);
        const container = document.createElement('div');
        container.appendChild(img);
        container.appendChild(document.createElement('br'));
        container.appendChild(title);
        return {
          domNodes: [container]
        }; // Return DOM nodes instead of HTML string
      }
      return true;
    },
    datesSet: (info) => {
      const currentMonth = info.view.currentStart.getMonth() + 1;
      updateBackground(info.view.currentStart);
    }
  });

  calendar.render();
});
<script src='https://cdn.jsdelivr/npm/[email protected]/index.global.min.js'></script>


<div id="calendar"></div>



<script>
  // consts better sourced from elsewhere - ajax for example
  const monthColors = [
    "#FF5733", "#33B5E5", "#A569BD", "#58D68D", "#F4D03F",
    "#FF8C00", "#4682B4", "#DC143C", "#20B2AA", "#FF6347",
    "#2E8B57", "#B22222"
  ];

  const events = [{
      title: 'Birthday',
      start: '2025-03-17',
      color: 'transparent',
      textColor: 'black',
      imageurl: 'https://images.freeimages/image/previews/1db/birthday-quote-png-celebration-5690238.png'
    },
    {
      title: 'Marriage',
      start: '2025-03-19',
      end: '2025-03-20',
      color: '#8E9A75',
      textColor: 'white',
      imageurl: 'https://clipart-library/img/812312.png'
    }
  ];
  </script>

You seem to be using the v3 of the fullCalendar which integrates with jQuery. If you read the v3 documentation it supports a viewRender event. The callback provides a view argument in which you can find the current month.

So, you can remove the timeout alltogether, and add the following event handler to your fullCalendar configuration

viewRender: function(view, element){
    const viewMonthDate = view.dateProfile.date.toDate(); // convert to normal date, as it is held as a moment instance
    updateBackground(viewMonthDate)
},

Full example based on original code

$(document).ready(function() {
  var monthColors = [
    "#FF5733", // January - Red-Orange
    "#33B5E5", // February - Blue
    "#A569BD", // March - Purple
    "#58D68D", // April - Green
    "#F4D03F", // May - Yellow
    "#FF8C00", // June - Orange
    "#4682B4", // July - Steel Blue
    "#DC143C", // August - Crimson
    "#20B2AA", // September - Light Sea Green
    "#FF6347", // October - Tomato
    "#2E8B57", // November - Sea Green
    "#B22222" // December - Fire Brick
  ];

  function updateBackground(date) {
    var month = date.getMonth(); // Get displayed month
    console.log("Updating background for month:", month + 1); // Debugging log
    $("body").css("background-color", monthColors[month]);
  }

  $('#calendar').fullCalendar({
    header: {
      left: '',
      center: 'title'
    },
    events: [{
      title: 'Marriage',
      start: '2025-03-17',
      color: 'transparent',
      textColor: 'black',
      imageurl: 'birthday.png'
    }, {
      title: 'Marriage',
      start: '2025-03-19',
      end: '2025-03-20',
      color: '#8E9A75',
      textColor: 'white',
      imageurl: 'birthday.png'
    }],
    eventRender: function(event, eventElement) {
      if (event.imageurl) {
        eventElement.prepend("<img src='" + event.imageurl + "' width='80' height='80' >");
      }
      return ['all', event.tags].indexOf($('#event_selector option:selected').val()) >= 0;
    },
    datesSet: function(info) {
      var currentMonth = calendar.getDate().getMonth() + 1;
      console.log("Currently viewed month:", currentMonth);
    },
    viewRender: function(view, element) {
      const viewMonthDate = view.dateProfile.date.toDate(); // convert to normal date, as it is held as a moment instance
      updateBackground(viewMonthDate)
    },
  });
});
<script src="https://cdn.jsdelivr/npm/jquery@3/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/min/moment.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/fullcalendar.min.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr/npm/[email protected]/dist/fullcalendar.min.css" />

<div id='calendar'></div>

  1. updateBackground is not called in datesSet.
  2. Remove the setTimeout and call updateBackground directly after the calendar is initialized.
  3. In the datesSet callback, you should use info to get the current date instead of using calendar.getDate().

Finally, here is an example of the code that you can save directly as an HTML file and see if it achieves the effect you want.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>FullCalendar Month Background</title>
  <!-- FullCalendar v3 CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css"/>
  <!-- jQuery -->
  <script src="https://cdnjs.cloudflare/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <!-- Moment.js -->
  <script src="https://cdnjs.cloudflare/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
  <!-- FullCalendar v6 JS -->
  <script src='https://cdn.jsdelivr/npm/[email protected]/index.global.min.js'></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
    }
    #calendar {
      max-width: 900px;
      margin: 50px auto;
    }
  </style>
</head>
<body>
  <div id="calendar"></div>

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      var monthColors = [
        "#FF5733",   // January - Red-Orange
        "#33B5E5",   // February - Blue
        "#A569BD",   // March - Purple
        "#58D68D",   // April - Green
        "#F4D03F",   // May - Yellow
        "#FF8C00",   // June - Orange
        "#4682B4",   // July - Steel Blue
        "#DC143C",   // August - Crimson
        "#20B2AA",   // September - Light Sea Green
        "#FF6347",   // October - Tomato
        "#2E8B57",  // November - Sea Green
        "#B22222"   // December - Fire Brick
      ];

      function updateBackground(month) {
        $("body").css("background-color", monthColors[month]);
      }

      var calendarEl = document.getElementById('calendar');

      var calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'dayGridMonth',
        headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        initialDate: new Date(),
        datesSet: function(dateInfo) {
            var currentDate = dateInfo.view.currentStart.getMonth();
            updateBackground(currentDate);
        },
      });
      updateBackground(new Date().getMonth());
      calendar.render();
    });
    
  </script>
</body>
</html>

To fix it so that the background colors change when the months change

  • I added updateBackground() to the dataSet handler
  • and passed updateBackground() the date from the calendar object

However

  • I initialized the calendar in a different way (see below)
  • I used v6 of the plugin while some of your code, eg. your eventRender handler references v3 https://fullcalendar.io/docs/v3/eventRender while v4 and later have use one argument instead of two

It looks like in your code updateBackground() was only fired once by the setTimeout but never again by any of your UI interactions which would be handled by the dateSet handler.

The larger problem may be due to how you initialized your calendar plugin. I've never used it before so I just went by the quickstart docs.

I wasn't able to fix the image loading issue

document.addEventListener('DOMContentLoaded', function() {

  var monthColors = [
    "#FF5733", // January - Red-Orange
    "#33B5E5", // February - Blue
    "#A569BD", // March - Purple
    "#58D68D", // April - Green
    "#F4D03F", // May - Yellow
    "#FF8C00", // June - Orange
    "#4682B4", // July - Steel Blue
    "#DC143C", // August - Crimson
    "#20B2AA", // September - Light Sea Green
    "#FF6347", // October - Tomato
    "#2E8B57", // November - Sea Green
    "#B22222" // December - Fire Brick
  ];

  function updateBackground(date) {
    var month = date.getMonth(); // Get displayed month
    console.log("Updating background for month:", month + 1); // Debugging log
    $("body").css("background-color", monthColors[month]);
  }


  var calendar = new FullCalendar.Calendar(document.getElementById('calendar'), {
    initialView: 'dayGridMonth',
    header: {
      left: '',
      center: 'title'
    },
    events: [{
        title: 'Marriage',
        start: '2025-03-17',
        color: 'transparent',
        textColor: 'black',
        imageurl: 'birthday.png'
      },
      {
        title: 'Marriage',
        start: '2025-03-19',
        end: '2025-03-20',
        color: '#8E9A75',
        textColor: 'white',
        imageurl: 'birthday.png'
      }
    ],
    eventRender: function(event, eventElement) {
      if (event.imageurl) {
        eventElement.prepend("<img src='" + event.imageurl + "' width='80' height='80' >");
      }
      return ['all', event.tags].indexOf($('#event_selector option:selected').val()) >= 0;
    },
    datesSet: function(info) {
      var currentMonth = calendar.getDate().getMonth() + 1;
      updateBackground(calendar.getDate())
      console.log("Currently viewed month:", currentMonth);
    }
  });

  setTimeout(function() {
    updateBackground(new Date());
  }, 100);
  calendar.render();
});
<script src="https://code.jquery/jquery-3.7.1.min.js"></script>
<script src='https://cdn.jsdelivr/npm/[email protected]/index.global.min.js'></script>


<div id="calendar"></div>

发布评论

评论列表(0)

  1. 暂无评论