随机图像函数 Javascript
2021-04-01
92
我正在尝试编写我的第一个自定义 JavaScript 函数,但遇到了一些障碍。
我试图在我的网页上放置三个缩略图,并让我的代码从众多图像中抓取三张并在加载时显示它们。 我遇到的问题围绕着图像重复或能够处理两次选择图像的情况(这是类似的问题)。 我尝试了许多不同的条件,但似乎无法突破。
这是我的代码:
let imgThumbnails = document.querySelectorAll('.img-fluid');
let chosenNums = [];
let imgNumber = () => { //object random
return Math.floor(Math.random() * (Object.keys(pictures).length));
}
const pictures = {
0 : { "src" : "Images - Copy/crack_plant.jpg", "alt" : "Seedling growing through bricks"},
1 : { "src" : "Images - Copy/desert_botanical.jpg", "alt" : "Phoenix's Desert Botanical Garden"},
2 : { "src" : "Images - Copy/LookUp.jpg", "alt" : "Looking up through forest"},
3 : { "src" : "Images - Copy/LookUpLeaves.jpg", "alt" : "Looking up at leaves"},
4 : { "src" : "Images - Copy/Road_Through_Trees.jpg", "alt" : "A path covered by trees"},
5 : { "src" : "Images - Copy/Sand.jpg", "alt" : "Tiny balls of sand formed by crabs"},
6 : { "src" : "Images - Copy/Snow.jpg", "alt" : "Powder day at Breckenridge"},
}; // these images are hosted locally for me at the moment
//attempt 1
const imgPopulate = () => {
imgThumbnails.forEach( a => {
let pictureNum = imgNumber();
while (!chosenNums.includes(pictureNum) && chosenNums.length <= 3) {
a.src = pictures[pictureNum].src;
chosenNums.push(pictureNum);
}
});
}
imgPopulate();
//attempt 2
while (chosenNums.length <= 3) {
let pictureNum = imgNumber();
if(chosenNums.includes() !== pictureNum) {
for(let i = 0; i <=3; i++) {
imgThumbnails[i].src = pictures[pictureNum].src
chosenNums.push(pictureNum);
}
}
}
//attempt 3
do {
for(let i = 0; i <=3; i++) {
let pictureNum = imgNumber();
if(chosenNums.includes() !== pictureNum) {
imgThumbnails[i].src = pictures[pictureNum].src
chosenNums.push(pictureNum);
} else {
continue;
}
}
} while (chosenNums.length <= 3);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="views/css/bootstrap.min.css" rel="stylesheet">
<title>Showin Photos</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<img id = "photo1" class="img-fluid" src="" alt="">
</div>
<div class="col">
<img id = "photo2" class="img-fluid" src="" alt="">
</div>
<div class="col">
<img id = "photo3" class="img-fluid" src="" alt="">
</div>
</div>
</div>
<script src="views/js/bootstrap.min.js"></script>
<script src="index.js"></script>
</body>
</html>
尝试: 1:这个有时有效,除非它从已经使用过的图片对象中命中一个数字。然后它只会显示一个空白的缩略图。我相信这个问题是因为它使用了 forEach。所以它只对每个项目运行一次,即使它之前被使用过,我的 while 循环也不会影响它。
2/3:我从这两次尝试中都遇到了同样的问题。这些尝试偶尔会将同一张图片用于不同的缩略图。我还收到:“未捕获的类型错误:无法设置未定义的属性‘src’”,这与“pictures[pictureNum].src”有关,但所有缩略图仍然充满了图像?!?!
如果可以提供任何帮助,无论是帮助修复此代码还是如果您有其他方法,我都应该尝试编写此代码,以便我可以尝试。 正如我所说,这是我第一次尝试自定义函数,我觉得我的视野变得狭窄,无法真正从不同角度看待它。
谢谢!
2个回答
您可以使用以下概念:
- 使用 Object.values 将图片转换为数组,然后对数组进行打乱。
// see shuffle options in the snippet
const data = shuffle(Object.values(pictures));
- 由于数据现在已打乱,只需使用 array.slice 从数组中获取前 3 个项目即可。>
const selected = data.slice(0, 3);
如果您使用 Flavios Copes 排序,则可以在一行中完成此操作随机播放:
const selected = Object.values(pictures).sort(() => Math.random() - 0.5).slice(0, 3);
const pictures = {
0: {
"src": "Images - Copy/crack_plant.jpg",
"alt": "Seedling growing through bricks"
},
1: {
"src": "Images - Copy/desert_botanical.jpg",
"alt": "Phoenix's Desert Botanical Garden"
},
2: {
"src": "Images - Copy/LookUp.jpg",
"alt": "Looking up through forest"
},
3: {
"src": "Images - Copy/LookUpLeaves.jpg",
"alt": "Looking up at leaves"
},
4: {
"src": "Images - Copy/Road_Through_Trees.jpg",
"alt": "A path covered by trees"
},
5: {
"src": "Images - Copy/Sand.jpg",
"alt": "Tiny balls of sand formed by crabs"
},
6: {
"src": "Images - Copy/Snow.jpg",
"alt": "Powder day at Breckenridge"
},
};
// shuffle array using Durstenfeld shuffle algorithm
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// convert to an array and shuffle
const data = shuffle(Object.values(pictures));
// grab the first 3
const selected = data.slice(0, 3);
console.info(selected);
// one liner using Flavios Copes sort
console.info(Object.values(pictures).sort(() => Math.random() - 0.5).slice(0, 3));
Samuel Goldenbaum
2021-04-01
好的,首先,您不需要具有数字键的对象。这本质上是一个数组。与对象相比,数组可以更简单地为您提供所需的功能。
您只需要使用
while
循环来检查它刚刚从数组中挑选的随机图像是否已经是挑选的图像,您可以通过单独存储生成的随机图像来做到这一点。
let pics = document.querySelectorAll(".img-fluid");
let chosenNums = [];
let getRandom = () => {
return Math.floor(Math.random() * pictures.length);
}
// An object with sequential numbers for keys is essentially an array
// so just use an Array.
const pictures = [
{ "src" : "Images - Copy/crack_plant.jpg", "alt" : "Seedling growing through bricks"},
{ "src" : "Images - Copy/desert_botanical.jpg", "alt" : "Phoenix's Desert Botanical Garden"},
{ "src" : "Images - Copy/LookUp.jpg", "alt" : "Looking up through forest"},
{ "src" : "Images - Copy/LookUpLeaves.jpg", "alt" : "Looking up at leaves"},
{ "src" : "Images - Copy/Road_Through_Trees.jpg", "alt" : "A path covered by trees"},
{ "src" : "Images - Copy/Sand.jpg", "alt" : "Tiny balls of sand formed by crabs"},
{ "src" : "Images - Copy/Snow.jpg", "alt" : "Powder day at Breckenridge"}
];
// Keep looping until we have 3 randoms
while(chosenNums.length < 3){
let random = getRandom(); // Get a random
// Check to see if the random is NOT already in the output array
if(!chosenNums.includes(random)){
chosenNums.push(random); // It's not so add it
}
}
// Now that the output array has 3 randoms in it, loop over them
chosenNums.forEach(function(num, index){
// Set up the img element corresponding to the loop index
// with the data from the picture corresponding to the index
// in the array of randoms
pics[index].src = pictures[num].src;
pics[index].alt = pictures[num].alt;
});
<div class="container">
<div class="row">
<div class="col">
<img id = "photo1" class="img-fluid">
</div>
<div class="col">
<img id = "photo2" class="img-fluid">
</div>
<div class="col">
<img id = "photo3" class="img-fluid">
</div>
</div>
</div>
Scott Marcus
2021-04-01