简体   繁体   中英

How can I display images based on the title of the image in javascript?

I have a folder with images with every letter. Given a sentence, I want to be able to iterate through all the letters in the sentence and display each letter associated image for 3 seconds at a time. For example, for the sentence "grape", the picture thats titled "g" would display for 3 seconds, then continue to the next letter, etc. Right now, I am displaying the images in the order they are placed in the folder. I am confused about how I can implement the changes I am looking for as I am a beginner in javascript. Thank you in advance, here is what I have now:

 var index = 0; change(); var phrase = "my sentence"; function change() { var pics = document.getElementsByClassName('pictures'); for(var i = 0; i < pics.length; i++) { pics[i].style.display = "none"; } for (var j = 0; j < phrase.length; j++) { for (var k = 0; k < pictures.length; k++) { var image = pictures[k].getElementsByTagName("img")[0]; var title = image.getAttribute("title"); if (phrase[j] == title) { pictures[k].style.display = "block"; } } } setTimeout(change, 3000); }
 <section> <img class="slides" src="letter_images/a.jpg" style="width:50%"> <img class="slides" src="letter_images/b.jpg" style="width:50%"> <img class="slides" src="letter_images/c.jpg" style="width:50%"> <img class="slides" src="letter_images/d.jpg" style="width:50%"> <img class="slides" src="letter_images/e.jpg" style="width:50%"> <img class="slides" src="letter_images/f.jpg" style="width:50%"> <img class="slides" src="letter_images/g.jpg" style="width:50%"> <img class="slides" src="letter_images/h.jpg" style="width:50%"> <img class="slides" src="letter_images/i.jpg" style="width:50%"> <img class="slides" src="letter_images/j.jpg" style="width:50%"> <img class="slides" src="letter_images/k.jpg" style="width:50%"> <img class="slides" src="letter_images/l.jpg" style="width:50%"> <img class="slides" src="letter_images/m.jpg" style="width:50%"> <img class="slides" src="letter_images/n.jpg" style="width:50%"> <img class="slides" src="letter_images/o.jpg" style="width:50%"> <img class="slides" src="letter_images/p.jpg" style="width:50%"> <img class="slides" src="letter_images/q.jpg" style="width:50%"> <img class="slides" src="letter_images/r.jpg" style="width:50%"> <img class="slides" src="letter_images/s.jpg" style="width:50%"> <img class="slides" src="letter_images/t.jpg" style="width:50%"> <img class="slides" src="letter_images/u.jpg" style="width:50%"> <img class="slides" src="letter_images/v.jpg" style="width:50%"> <img class="slides" src="letter_images/w.jpg" style="width:50%"> <img class="slides" src="letter_images/x.jpg" style="width:50%"> <img class="slides" src="letter_images/y.jpg" style="width:50%"> <img class="slides" src="letter_images/z.jpg" style="width:50%"> </section>

I propose to loop over every letters of the sentence. Each letter will be displayed at index * 3000ms (where index is the index of the letter in the sentence - first letter index = 0, second letter index = 1, ...)

Here is a code example

 const imgLetter = document.getElementById('letter'); const sentence = 'hello world'; sentence .split('') .filter(letter => /[az ]/i.test(letter)) // consider only letters and space .forEach((letter, index) => { setTimeout(_ => { letter = letter !== ' ' ? letter : 'Rest'; imgLetter.src = `letter_images/${letter}.jpg`; imgLetter.alt = letter; }, index * 3000); });
 <section> <img class="slides" src="" style="width:50%" id="letter"> </section>

You need to loop through the letters in the phrase variable to find each letter, one by one. From that, you need to find out where it would appear in the alphabet (the letters string below). This should give you a number from 0 to 25. This should match an index number in your slides collection, so you can show the one with the matching index number.

    var index = 0;
    var phrase = "my sentence";
    var letters = "abcdefghijklmnopqrstuvwxyz";
    var tt;

    function change() {
         var pics = document.getElementsByClassName('slides');

         for(var i = 0; i < pics.length; i++) { 
             pics[i].style.display = "none"; 
         }

         let thisLetter = phrase.substr(index, 1);
         if (thisLetter != " ") {
           let thisPos = letters.indexOf(thisLetter);
           pics[thisPos].style.display = "block";
         } else {
           pics[pics.length - 1].style.display = "block";
         }
        index++;
        if (index != phrase.length) {
          tt = setTimeout(change, 3000);
        } else {
          for(var i = 0; i < pics.length; i++) { 
             pics[i].style.display = "none"; 
          }
        }
     }

This can't be tested without all of the images being available. The code does run, but you will need to check it locally to be absolutely sure.

Here is another approach. Load in all the images you're going to need to need and then loop through them all. This way you won't have to load in extra images. If your phrase is long and has duplicate letters and contains most letters, ATD's approach might be better.

 let phrase = 'grape', index = 0; output = document.querySelector('#output'); //Frist we create the phrase with images, all hidden for (let i = 0; i < phrase.length; i++) { output.innerHTML += `<img class="slides" src="letter_images/${phrase[i]}.jpg" style="width:50%" alt="${phrase[i]}">` } //Now we show each one, one at a time var loop = window.setInterval(showNextLetter, 3000 /*3 sec*/); showNextLetter(); function showNextLetter() { let nextLetter = output.children[index], oldLetter = document.querySelector('.slides.shown'); //Make sure it exists if (oldLetter) oldLetter.classList.remove('shown'); nextLetter.classList.add('shown'); index++; if (index >= phrase.length) index = 0; }
 .slides { display: none; } .slides.shown { display: block; }
 <div id="output"></div>

As it has been pointed out by ATD, setTimeout does not guarantee that the action will be performed at the requested interval , so I've tried to look for a solution without setTimeout .

My idea is to create the full sentence with a loop in javascript and then to use a CSS animation to display one image at a time

 const sentence = document.getElementById('sentence'); const mySentence = 'hello world'; const letters = mySentence.split('').filter(letter => /[az ]/i.test(letter)); sentence.style.setProperty('--letter-count', letters.length); letters.forEach(letter => { const imgLetter = document.createElement('img'); letter = letter !== ' ' ? letter : 'Rest'; imgLetter.src = `letter_images/${letter}.jpg`; imgLetter.alt = letter; sentence.append(imgLetter); });
 #sentence { display: flex; overflow: hidden; } /* images must have #sentence same size */ #sentence, #sentence > img { width: 200px; height: 200px; } #sentence > img:first-child { animation-name: slide; animation-duration: calc(3s * var(--letter-count)); animation-timing-function: steps(var(--letter-count), end); animation-fill-mode: forwards; } /* -200px = minus the width of #sentence */ @keyframes slide { from {margin-left: 0} to {margin-left: calc(-200px * var(--letter-count))} }
 <section id="sentence"></section>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM