SharePoint Online中jQuery FullCalendar二次加载异常求助
Hey there! Let's break down this tricky FullCalendar issue you're hitting in SharePoint Online. That intermittent jQuery(...).fullCalendar is not a function error when navigating back to your homepage is super common in classic SharePoint's partial page load environment—here's what's going on and how to fix it:
1. SharePoint's Partial Page Navigation Quirk
Classic SharePoint often uses partial page updates (instead of full page reloads) when navigating between pages. Even though your network panel shows fullcalendar.js is loaded, the script's functions don't reattach to the new DOM context when you return to the homepage. The initial document.ready trigger only fires once on the first full page load, not on partial navigations.
2. Fix: Force Reliable Script Initialization & Cleanup
Update your code to explicitly verify dependencies, handle reinitialization, and clean up existing calendar instances. Here's the revised version with comments explaining the changes:
(function() { // Ensure SharePoint core scripts are loaded first SP.SOD.executeFunc('sp.core.js', 'SP.ClientContext', initDependencyCheck); // Initialize cache object to avoid undefined errors window._cache = window._cache || {}; function initDependencyCheck() { // Verify jQuery exists; load it dynamically if missing if (typeof jQuery === 'undefined') { loadScript('/sites/web/modules/jquery-3.2.1.min.js', loadFullCalendar); } else { loadFullCalendar(); } } function loadFullCalendar() { // Verify FullCalendar is loaded; load dynamically if missing if (typeof jQuery.fn.fullCalendar === 'undefined') { loadScript('/sites/web/modules/fullcalendar.js', startCalendarWorkflow); } else { startCalendarWorkflow(); } } function startCalendarWorkflow() { // Kick off your SharePoint AJAX call AjaxCallToSharePoint(); } // Helper function to load scripts dynamically function loadScript(src, callback) { const script = document.createElement('script'); script.src = src; script.onload = callback; document.head.appendChild(script); } function AjaxCallToSharePoint() { const DateRAngeFormat = 'YYYY-MM-DDT00'; const ThreeMonthsEarlier = moment().add(-3, 'months').format(DateRAngeFormat); const ThreeMonthsFromNow = moment().add(3, 'months').format(DateRAngeFormat); const url = `${_spPageContextInfo.webAbsoluteUrl}/_api/web/lists/getbytitle('Program')/items? $select=Bokning_x0020_fr_x00e5_n%2CBokning_x0020_till%2CTitle%2CMax_x0020_antal_x0020_platser%2CKontaktperson&$filter=Bokning_x0020_fr_x00e5_n%20ge%20datetime'${ThreeMonthsEarlier}%3A00%3A00'%20and%20Bokning_x0020_fr_x00e5_n%20le%20datetime'${ThreeMonthsFromNow}%3A00%3A00'`; const call = jQuery.ajax({ url: url, type: "GET", dataType: "json", headers: { Accept: "application/json;odata=verbose" } }); call.done(function (data) { window._cache.globalArray = data.d.results; // Fixed typo: RenderCalender → RenderFullCalender (matches your function name) RenderFullCalender(window._cache.globalArray); RenderDatePicker(); }); call.fail(function (jqXHR, textStatus) { console.error('AJAX call failed:', textStatus); }); } function RenderFullCalender(array) { // Clean up existing calendar instance to avoid conflicts const $calendar = jQuery('#calendar'); if ($calendar.data('fullCalendar')) { $calendar.fullCalendar('destroy'); } // Initialize the calendar $calendar.fullCalendar({ // Add your calendar options here events: array // Pass your SharePoint data to the calendar }); } })();
Critical Changes in This Code:
- Uses SharePoint's
SP.SOD.executeFuncto ensure core SP scripts load before our code runs - Dynamically loads jQuery/FullCalendar if they're missing from the current DOM context
- Adds a cache initialization to avoid
undefinederrors withwindow._cache - Fixes the typo
RenderCalender→RenderFullCalender(this could have been causing silent failures!) - Destroys existing calendar instances before reinitializing to prevent duplicate bindings
3. Bonus Check: FullCalendar Version Compatibility
If you're using FullCalendar v4 or newer, the old jQuery('#calendar').fullCalendar() syntax is deprecated. You'll need to use the modern constructor instead:
function RenderFullCalender(array) { const calendarEl = document.getElementById('calendar'); // Clean up existing instance if (window.calendarInstance) { window.calendarInstance.destroy(); } // Initialize modern FullCalendar window.calendarInstance = new FullCalendar.Calendar(calendarEl, { events: array // Add your options here }); window.calendarInstance.render(); }
4. Last Resort: Disable Partial Page Navigation
If you don't mind sacrificing some performance for simplicity, you can disable SharePoint's partial page loads to force full page reloads every time:
// Add this at the top of your script if (typeof SP !== 'undefined' && SP.UI && SP.UI.ModalDialog) { SP.UI.ModalDialog.showModalDialog({ url: window.location.href, dialogReturnValueCallback: () => window.location.reload() }); }
内容的提问来源于stack exchange,提问作者AllramEst

