如何在JavaScript中为每个HTML类实例设置独立变量?
Ah, classic global variable pitfall! The issue here is that your single global counter is being shared across all your scoreboard divs—so clicking one updates the count for everyone, leading to those conflicting states. Let's fix this by giving each div its own independent state, and I'll walk you through a few solid approaches.
Approach 1: Use HTML5 dataset to Store Per-Element State
This is the simplest approach for basic use cases. We'll store the current image index directly on each div element using the data-* attribute, so each scoreboard keeps track of its own cycle state.
HTML
<div class="cricket-scoreboard">Scoreboard 1</div> <div class="cricket-scoreboard">Scoreboard 2</div> <div class="cricket-scoreboard">Scoreboard 3</div>
JavaScript
// Define your background image array const backgroundImages = [ 'score-bg-1.jpg', 'score-bg-2.jpg', 'score-bg-3.jpg', 'score-bg-4.jpg' ]; // Get all scoreboard elements const scoreboards = document.querySelectorAll('.cricket-scoreboard'); // Initialize and bind click events to each board scoreboards.forEach(board => { // Set initial index on the element's dataset board.dataset.currentIndex = '0'; // Optional: Set initial background board.style.backgroundImage = `url(${backgroundImages[0]})`; board.addEventListener('click', () => { // Get the current index from the element's dataset let currentIndex = parseInt(board.dataset.currentIndex); // Cycle to next image (use modulo for loop behavior) currentIndex = (currentIndex + 1) % backgroundImages.length; // Update the background board.style.backgroundImage = `url(${backgroundImages[currentIndex]})`; // Save the new index back to the dataset board.dataset.currentIndex = currentIndex.toString(); }); });
Why this works: Each div holds its own currentIndex value in its dataset, so clicks on one don't affect the state of others.
Approach 2: Use Closures to Encapsulate State
If you prefer keeping state in JavaScript rather than on the DOM, closures are a great option. Each click handler will have access to a unique currentIndex variable tied to its specific div.
JavaScript
const backgroundImages = [ 'score-bg-1.jpg', 'score-bg-2.jpg', 'score-bg-3.jpg' ]; document.querySelectorAll('.cricket-scoreboard').forEach(board => { // This variable is scoped to each iteration of the loop—unique per div let currentIndex = 0; board.style.backgroundImage = `url(${backgroundImages[currentIndex]})`; board.addEventListener('click', () => { currentIndex = (currentIndex + 1) % backgroundImages.length; board.style.backgroundImage = `url(${backgroundImages[currentIndex]})`; }); });
Why this works: The currentIndex variable lives in the scope of the forEach callback for each div. When the click handler is created, it "closes over" this variable, ensuring each div has its own independent count.
Approach 3: Use a Class for Scalability
If you plan to add more features to your scoreboards later (like resetting the cycle, displaying scores, etc.), encapsulating the logic in a class makes your code cleaner and more maintainable.
JavaScript
class CricketScoreboard { constructor(element, bgImages) { this.element = element; this.bgImages = bgImages; this.currentIndex = 0; // Set initial background this.updateBackground(); // Bind click event (arrow function preserves `this` context) this.element.addEventListener('click', () => this.cycleBackground()); } updateBackground() { this.element.style.backgroundImage = `url(${this.bgImages[this.currentIndex]})`; } cycleBackground() { this.currentIndex = (this.currentIndex + 1) % this.bgImages.length; this.updateBackground(); } // Optional: Add a reset method if needed reset() { this.currentIndex = 0; this.updateBackground(); } } // Initialize each scoreboard const backgroundImages = [ 'score-bg-1.jpg', 'score-bg-2.jpg', 'score-bg-3.jpg' ]; document.querySelectorAll('.cricket-scoreboard').forEach(board => { new CricketScoreboard(board, backgroundImages); });
Why this works: Each CricketScoreboard instance has its own currentIndex property, so all state is fully isolated per scoreboard. This is perfect if you want to expand functionality down the line.
All three approaches will solve your state conflict issue—pick the one that best fits your project's complexity!
内容的提问来源于stack exchange,提问作者JakAttk123

