请求:基于HTML/CSS/JS实现静态网页元素定时轮换功能
Got it, let's tackle this exact requirement—no server-side code needed, just vanilla HTML, CSS, and JavaScript. We'll build a system that:
- Shows 3 elements at a time, rotating to the next group every hour
- Rotates the entire list of elements (shuffling their order top-to-bottom) once per day
- Persists state across page refreshes so rotations don't reset when the user reloads
Here's a complete, working example:
HTML Structure
We'll use a container for all elements, with each element as a .item div. I've added 9 sample items (3 groups of 3) to demonstrate, but you can adjust the number as needed.
<div class="items-container"> <div class="item">Element 1 (Group 1)</div> <div class="item">Element 2 (Group 1)</div> <div class="item">Element 3 (Group 1)</div> <div class="item">Element 4 (Group 2)</div> <div class="item">Element 5 (Group 2)</div> <div class="item">Element 6 (Group 2)</div> <div class="item">Element 7 (Group 3)</div> <div class="item">Element 8 (Group 3)</div> <div class="item">Element 9 (Group 3)</div> </div>
CSS Styling
We'll hide all elements by default, then only show the ones marked with the .active class. Feel free to adjust the styling to match your design (flex, grid, etc.).
.items-container { max-width: 800px; margin: 2rem auto; padding: 0 1rem; } .item { display: none; padding: 1.5rem; margin: 1rem 0; background: #f0f0f0; border-radius: 8px; } .item.active { display: block; }
JavaScript Logic
This handles both rotation cycles and persists state using localStorage so rotations don't reset on page refresh.
// Configuration - adjust these values to match your needs const CONFIG = { groupSize: 3, // Number of elements per hourly group hourlyRotationMs: 3600000, // 1 hour in milliseconds dailyRotationMs: 86400000, // 24 hours in milliseconds }; // Get DOM elements const itemsContainer = document.querySelector('.items-container'); const allItems = Array.from(itemsContainer.querySelectorAll('.item')); // State management with localStorage function getCurrentState() { const savedState = localStorage.getItem('rotationState'); if (savedState) { return JSON.parse(savedState); } // Default state if no saved data return { currentGroupIndex: 0, lastHourlyRotation: Date.now(), lastDailyRotation: Date.now(), itemOrder: allItems.map(item => item.innerHTML), // Save initial content order }; } function saveState(state) { localStorage.setItem('rotationState', JSON.stringify(state)); } // Update the DOM to show the current active group function updateActiveGroup(groupIndex) { // Remove active class from all items allItems.forEach(item => item.classList.remove('active')); // Calculate start/end indices for the current group const startIndex = groupIndex * CONFIG.groupSize; const endIndex = startIndex + CONFIG.groupSize; // Add active class to items in the current group allItems.slice(startIndex, endIndex).forEach(item => item.classList.add('active')); } // Rotate to the next hourly group function rotateHourlyGroup() { const state = getCurrentState(); // Calculate how many groups we have const totalGroups = Math.ceil(allItems.length / CONFIG.groupSize); // Move to next group, loop back to 0 if we reach the end state.currentGroupIndex = (state.currentGroupIndex + 1) % totalGroups; state.lastHourlyRotation = Date.now(); saveState(state); updateActiveGroup(state.currentGroupIndex); } // Rotate the entire list of elements (top-to-bottom) function rotateDailyFullList() { const state = getCurrentState(); // Shift the first item to the end (adjust this line to reverse direction if needed) const firstItemContent = state.itemOrder.shift(); state.itemOrder.push(firstItemContent); // Update the DOM with the new order allItems.forEach((item, index) => { item.innerHTML = state.itemOrder[index]; }); state.lastDailyRotation = Date.now(); saveState(state); } // Calculate time remaining until next rotation and set timers function setupTimers() { const state = getCurrentState(); // Handle hourly rotation const timeSinceLastHourly = Date.now() - state.lastHourlyRotation; const nextHourlyDelay = Math.max(0, CONFIG.hourlyRotationMs - timeSinceLastHourly); setTimeout(() => { rotateHourlyGroup(); // Repeat hourly rotation indefinitely setInterval(rotateHourlyGroup, CONFIG.hourlyRotationMs); }, nextHourlyDelay); // Handle daily rotation const timeSinceLastDaily = Date.now() - state.lastDailyRotation; const nextDailyDelay = Math.max(0, CONFIG.dailyRotationMs - timeSinceLastDaily); setTimeout(() => { rotateDailyFullList(); // Repeat daily rotation indefinitely setInterval(rotateDailyFullList, CONFIG.dailyRotationMs); }, nextDailyDelay); } // Initialize the app function init() { const state = getCurrentState(); // Update the DOM to match saved item order (in case of daily rotation) allItems.forEach((item, index) => { item.innerHTML = state.itemOrder[index]; }); // Show the current active group updateActiveGroup(state.currentGroupIndex); // Set up rotation timers setupTimers(); } // Start the app when the page loads window.addEventListener('DOMContentLoaded', init);
How It Works
- State Persistence: We use
localStorageto track the current group, last rotation times, and element order. This means if the user refreshes the page, rotations pick up right where they left off. - Hourly Group Rotation: Every hour, we switch to the next group of 3 elements. If we reach the last group, we loop back to the first one.
- Daily Full Rotation: Once per day, we shift the entire list of elements (the first element moves to the end). If you want to reverse the direction (last element moves to the front), just modify the
rotateDailyFullListfunction: replaceshift()+push()withpop()+unshift(). - Timer Accuracy: We calculate the time remaining until the next rotation instead of just setting a fixed interval. This fixes issues where page refresh would reset the timer to a full hour/day.
You can adjust the CONFIG object to change group size, rotation intervals, or tweak the DOM structure/CSS to fit your design needs.
内容的提问来源于stack exchange,提问作者Taufiq Hidayah

