Google Calendar API获取事件列表、div渲染及RFC3339时间格式化问题
解决方案
核心调整说明
- 替换原有的
<pre>文本展示容器为div格式的事件列表容器,每个事件将独立生成<div>节点渲染 - 新增原生时间格式化函数,无需引入第三方库,可直接将RFC3339格式的时间转换为要求的中文可读格式,同时兼容全天事件(无具体时间的
event.start.date属性) - 调整原有的工具函数为事件渲染函数,适配新的展示逻辑
修改后完整代码
<!DOCTYPE html> <html> <head> <title>Google Calendar API 事件列表</title> <meta charset="utf-8" /> <style> /* 可选:给事件项加基础样式区分 */ .event-item { padding: 10px; margin: 8px 0; border: 1px solid #eee; border-radius: 4px; } .event-summary { font-weight: bold; margin-bottom: 4px; } .event-time { color: #666; font-size: 14px; } </style> </head> <body> <p>Google Calendar API 事件列表</p> <!--Add buttons to initiate auth sequence and sign out--> <button id="authorize_button" style="display: none;">授权</button> <button id="signout_button" style="display: none;">退出登录</button> <!-- 替换原有pre为事件列表容器 --> <div id="event-list"></div> <script type="text/javascript"> // Client ID and API key from the Developer Console var CLIENT_ID = '<YOUR_CLIENT_ID>'; var API_KEY = '<YOUR_API_KEY>'; // Array of API discovery doc URLs for APIs used by the quickstart var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"]; // Authorization scopes required by the API; multiple scopes can be // included, separated by spaces. var SCOPES = "https://www.googleapis.com/auth/calendar.readonly"; var authorizeButton = document.getElementById('authorize_button'); var signoutButton = document.getElementById('signout_button'); var eventListContainer = document.getElementById('event-list'); // 新增:RFC3339时间转中文可读格式函数 function formatRFC3339ToZh(timeStr, isAllDay = false) { const date = new Date(timeStr); const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }; if (!isAllDay) { options.hour = '2-digit'; options.minute = '2-digit'; options.hour12 = false; } return new Intl.DateTimeFormat('zh-CN', options).format(date); } // 新增:渲染单个事件到容器 function renderEvent(summary, timeStr) { const eventItem = document.createElement('div'); eventItem.className = 'event-item'; const summaryEl = document.createElement('div'); summaryEl.className = 'event-summary'; summaryEl.textContent = summary || '无标题事件'; const timeEl = document.createElement('div'); timeEl.className = 'event-time'; const isAllDay = !timeStr.includes('T'); // 全天事件的date属性没有T分隔符 timeEl.textContent = formatRFC3339ToZh(timeStr, isAllDay); eventItem.appendChild(summaryEl); eventItem.appendChild(timeEl); eventListContainer.appendChild(eventItem); } /** * On load, called to load the auth2 library and API client library. */ function handleClientLoad() { gapi.load('client:auth2', initClient); } /** * Initializes the API client library and sets up sign-in state * listeners. */ function initClient() { gapi.client.init({ apiKey: API_KEY, clientId: CLIENT_ID, discoveryDocs: DISCOVERY_DOCS, scope: SCOPES }).then(function () { // Listen for sign-in state changes. gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); // Handle the initial sign-in state. updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get()); authorizeButton.onclick = handleAuthClick; signoutButton.onclick = handleSignoutClick; }, function(error) { const errorEl = document.createElement('div'); errorEl.textContent = JSON.stringify(error, null, 2); eventListContainer.appendChild(errorEl); }); } /** * Called when the signed in status changes, to update the UI * appropriately. After a sign-in, the API is called. */ function updateSigninStatus(isSignedIn) { if (isSignedIn) { authorizeButton.style.display = 'none'; signoutButton.style.display = 'block'; listUpcomingEvents(); } else { authorizeButton.style.display = 'block'; signoutButton.style.display = 'none'; } } /** * Sign in the user upon button click. */ function handleAuthClick(event) { gapi.auth2.getAuthInstance().signIn(); } /** * Sign out the user upon button click. */ function handleSignoutClick(event) { gapi.auth2.getAuthInstance().signOut(); // 退出时清空事件列表 eventListContainer.innerHTML = ''; } /** * Print the summary and start datetime/date of the next ten events in * the authorized user's calendar. If no events are found an * appropriate message is printed. */ function listUpcomingEvents() { gapi.client.calendar.events.list({ 'calendarId': 'primary', 'timeMin': (new Date()).toISOString(), 'showDeleted': false, 'singleEvents': true, 'maxResults': 10, 'orderBy': 'startTime' }).then(function(response) { var events = response.result.items; const titleEl = document.createElement('h3'); titleEl.textContent = '即将到来的事件:'; eventListContainer.appendChild(titleEl); if (events.length > 0) { for (i = 0; i < events.length; i++) { var event = events[i]; var when = event.start.dateTime; if (!when) { when = event.start.date; } renderEvent(event.summary, when); } } else { const emptyEl = document.createElement('div'); emptyEl.textContent = '暂无即将到来的事件'; eventListContainer.appendChild(emptyEl); } }); } </script> <script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()"> </script> </body> </html>
内容的提问来源于stack exchange,提问作者webdev123
相关产品推荐
相关产品推荐

