如何在Google Web应用中条件加载CSS样式表并实现无刷新切换?
Great questions! Let's break this down step by step since we're dealing with client-side storage (localStorage) in a Google Web App, where server-rendered content can't directly access client-side data. Here's how to solve both problems:
Your original code injects Style1 directly via server-side HtmlService, but since localStorage lives in the user's browser, the server can't read it when rendering the initial HTML. We need to shift the style loading logic to the client side, using JavaScript to fetch the correct theme after the page loads.
Step 1: Update Your HTML <head>
Replace the server-side style injection with client-side script that fetches and applies the saved theme:
<head> <base target="_top"> <script> document.addEventListener('DOMContentLoaded', async function() { // Get saved theme from localStorage, default to 'Style1' if none exists const selectedTheme = localStorage.getItem('theme') || 'Style1'; // Fetch the CSS content from the server for the selected theme const cssContent = await google.script.run .withSuccessHandler(content => content) .getThemeCss(selectedTheme); // Create a style tag and inject the CSS const styleTag = document.createElement('style'); styleTag.textContent = cssContent; styleTag.setAttribute('data-theme', selectedTheme); // Mark for easy removal later document.head.appendChild(styleTag); // Store current theme for quick access during switching document.currentTheme = selectedTheme; }); </script> </head>
Step 2: Add a Server-Side Function (in Code.gs)
This function safely retrieves the CSS content for valid themes (to prevent malicious input):
function getThemeCss(themeName) { // Whitelist valid themes to avoid loading arbitrary files const validThemes = ['Style1', 'Style2']; if (!validThemes.includes(themeName)) { themeName = 'Style1'; } // Return the raw CSS content from the file return HtmlService.createHtmlOutputFromFile(themeName).getContent(); }
To switch themes on the fly, we'll add a trigger (like a button) that fetches the new theme's CSS, replaces the old style, and updates localStorage.
Step 1: Add a Toggle Button (in Your HTML)
Add a button anywhere in your body to trigger the theme switch:
<button onclick="toggleTheme()">Switch Theme</button>
Step 2: Add the Switching Logic (in Your HTML <script>)
Add this function alongside your page-load script:
async function toggleTheme() { // Determine the new theme to switch to const newTheme = document.currentTheme === 'Style1' ? 'Style2' : 'Style1'; // Fetch the new theme's CSS const cssContent = await google.script.run .withSuccessHandler(content => content) .getThemeCss(newTheme); // Remove the old theme's style tag const oldStyleTag = document.querySelector('style[data-theme]'); if (oldStyleTag) { oldStyleTag.remove(); } // Inject the new theme's CSS const newStyleTag = document.createElement('style'); newStyleTag.textContent = cssContent; newStyleTag.setAttribute('data-theme', newTheme); document.head.appendChild(newStyleTag); // Update current theme and save to localStorage document.currentTheme = newTheme; localStorage.setItem('theme', newTheme); }
Key Notes
- Security: The
getThemeCssfunction uses a whitelist to ensure only valid theme files are loaded, preventing users from loading arbitrary files via modifiedlocalStoragevalues. - Performance: Fetching CSS via
google.script.runis lightweight in this context, and replacing the style tag avoids full page reloads.
内容的提问来源于stack exchange,提问作者Partha S. Pal

