【问题标题】:Random image function Javascript随机图像函数Javascript
【发布时间】:2021-06-28 19:56:42
【问题描述】:

我正在尝试编写我的第一个自定义 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:我在这两次尝试中都遇到了同样的问题。这些尝试偶尔会为不同的缩略图使用相同的图片。我还得到一个:“Uncaught TypeError: Cannot set property 'src' of undefined”,这与“pictures[pictureNum].src”有关,但所有缩略图仍然充满图像?!?!

如果可以通过帮助修复此代码或如果您有其他方法可以提供任何帮助,我应该尝试编写此代码,以便我可以尝试。 正如我所说,这是我第一次尝试自定义功能,我觉得我得到了隧道视野,无法真正从不同的角度看待它。

谢谢!

【问题讨论】:

    标签: javascript html loops conditional-statements


    【解决方案1】:

    您可以使用以下概念:

    1. 使用Object.values 将图片转换为数组并打乱数组。
    // see shuffle options in the snippet
    const data = shuffle(Object.values(pictures));
    
    1. 由于数据现在被打乱,只需使用 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));

    【讨论】:

      【解决方案2】:

      好的,首先,您不需要具有数字键的对象。这本质上是一个数组。数组将比对象更简单地为您提供所需的功能。

      您只需要您的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>

      【讨论】:

        猜你喜欢
        • 2021-07-31
        • 2017-04-23
        • 2021-04-15
        • 2013-11-10
        • 1970-01-01
        • 1970-01-01
        • 2021-01-18
        • 2021-08-17
        • 2013-03-06
        相关资源
        最近更新 更多