从数组中抽取不重复随机图片的实现求助
Hey there! I totally get how annoying it is when the same random image pops up right after the last one—let’s sort this out with two solid solutions depending on what you need.
Option 1: Just Avoid Repeating the Previous Image
If you only want to make sure the next image isn’t the exact same as the last one (but don’t mind earlier repeats later), this simple approach works great. We’ll track the last selected image index using the element’s dataset (so it works even if you have multiple divs):
function myAnimation(element) { const images = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"]; // Get the last selected index from the element's dataset (default to -1 for first click) let lastIndex = parseInt(element.dataset.lastImageIndex) || -1; let random; // Keep generating a new random index until it's different from the last one do { random = Math.floor(Math.random() * images.length); } while (random === lastIndex); // Save the current index to the element's dataset for next time element.dataset.lastImageIndex = random; element.style.backgroundImage = images[random]; }
This way, every click will show a different image than the immediately preceding one, but you might see repeats of images from earlier clicks (e.g., pig → cat → pig is allowed here).
Option 2: Show All Images Without Repeat Before Cycling
If you want to make sure every image gets shown once before any repeats happen, we’ll maintain a list of remaining images to pick from. When the list is empty, we’ll reset it and start over:
For Multiple Divs (Using Dataset)
This version keeps track of remaining images per element, so each div has its own rotation:
function myAnimation(element) { const originalImages = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"]; // Initialize or load the remaining images from the element's dataset let remainingImages = JSON.parse(element.dataset.remainingImages); if (!remainingImages || remainingImages.length === 0) { remainingImages = [...originalImages]; // Make a copy of the original list } // Pick a random image from the remaining list const randomIndex = Math.floor(Math.random() * remainingImages.length); const selectedImage = remainingImages.splice(randomIndex, 1)[0]; // Update the dataset with the new remaining images element.dataset.remainingImages = JSON.stringify(remainingImages); element.style.backgroundImage = selectedImage; }
For a Single Div (Using Closure)
If you only have one div, a closure is a cleaner way to keep track of the remaining images without messing with dataset:
// Closure version: keeps state privately for the single div const myAnimation = (function() { const originalImages = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"]; let remainingImages = [...originalImages]; return function(element) { // Reset the list when all images have been used if (remainingImages.length === 0) { remainingImages = [...originalImages]; } const randomIndex = Math.floor(Math.random() * remainingImages.length); const selectedImage = remainingImages.splice(randomIndex, 1)[0]; element.style.backgroundImage = selectedImage; } })();
Both of these options will eliminate unwanted immediate repeats, and the second one ensures you cycle through all images before any repeats occur. Pick whichever fits your use case best!
内容的提问来源于stack exchange,提问作者Simon Revill

