1

Here is a code and a question itself:

<!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" />
    <title>Document</title>
    <style>
      .size {
        width: 100px;
        height: 100px;
      }

      .hiddenimage {
        display: none;
      }

      .activeimage {
        background-color: orange;
      }

      .text1color {
        color: green;
      }

      .text2color {
        color: red;
      }

      .text3color {
        color: blue;
      }

      .text4color {
        color: purple;
      }

      .text5color {
        color: brown;
      }
    </style>
  </head>
  <body>
    <div>
      <img
        class="image1isvisible size"
        onclick="switchToImage2()"
        src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Eo_circle_green_white_number-1.svg"
      />
      <img
        class="image2isvisible size"
        onclick="switchToImage3()"
        src="https://upload.wikimedia.org/wikipedia/commons/8/85/Eo_circle_red_white_number-2.svg"
      />
      <img
        class="image3isvisible size"
        onclick="switchToImage4()"
        src="https://upload.wikimedia.org/wikipedia/commons/1/1a/Eo_circle_blue_white_number-3.svg"
      />
      <img
        class="image4isvisible size"
        onclick="switchToImage5()"
        src="https://upload.wikimedia.org/wikipedia/commons/7/79/Eo_circle_purple_white_number-4.svg"
      />
      <img
        class="image5isvisible size"
        onclick="switchToImage1()"
        src="https://upload.wikimedia.org/wikipedia/commons/2/28/Eo_circle_brown_white_number-5.svg"
      />
    </div>
    <p class="text">
      If the localStorage is clear (on the first load), the state is like now:
      all five images are shown, all five images are not active (orange
      rectangular is not visible) and the colour of this text is default
      (black).<br />When user clicks on one of the images, four other images
      become hidden and only one image with the following number is shown. This
      text obtains colour of the visible image circle. The same happens on the
      folllowing clicks. So, images change sequentially (1, 2, 3, 4, 5, 1, 2, 3,
      4, 5, 1, 2, 3, ...) when user clicks on them and this text obtains the
      same colour as the circle on the image.<br />The last shown (=active,
      =current) image and the colour of the text should be stored in the
      localStorage.<br />
      On the page reload current active image and current text colour should be
      retrieved from the localStorage and shown.<br />Please, use
      <strong>only vanilla JS</strong>, no jQuery, no other libraries or
      frameworks. It is also important to preserve 5 independant functions
      (switchToImage2, ... switchToImage5, switchToImage1) for changing these 5
      images. Additions to these functions, new necessary functions or necessary
      editions (new classes, indeces, identificators, whatever) to the code in
      general are welcomed.<br />So, everyhing what was described above (instead
      of localStorage) is working as it should work and
      <strong>the only task is to store state in the localStorage</strong
      >.<br />Probably it will be necessary to store the whole function in the
      localStorage. For this purpose
      <a
        href="https://stackoverflow.com/a/38926742/17339653"
        target="_blank"
        rel="noopener noreferrer"
        >this</a
      >
      solution may be helpful.<br />If it is possible, it would be great to
      preserve the state with only one key in the localStorage. If it is
      impossible - you are welcomed to create different keys for visible image,
      its active orange rectangular and text colour.<br />I hope you will find
      this challenge interesting!<br />Could you copypaste my code, edit it and
      answer with a snippet that will possess all the abovementioned
      localStorage functionality?<br />Thank you a lot!
    </p>
    <script>
      const isText = document.querySelector(".text");
      const isimage1 = document.querySelector(".image1isvisible");
      const isimage2 = document.querySelector(".image2isvisible");
      const isimage3 = document.querySelector(".image3isvisible");
      const isimage4 = document.querySelector(".image4isvisible");
      const isimage5 = document.querySelector(".image5isvisible");

      function switchToImage2() {
        // removeotherstyle
        isimage1.classList.remove("activeimage");
        isimage3.classList.remove("activeimage");
        isimage4.classList.remove("activeimage");
        isimage5.classList.remove("activeimage");
        isimage1.classList.add("hiddenimage");
        isimage3.classList.add("hiddenimage");
        isimage4.classList.add("hiddenimage");
        isimage5.classList.add("hiddenimage");
        isText.classList.remove("text1color");
        isText.classList.remove("text3color");
        isText.classList.remove("text4color");
        isText.classList.remove("text5color");
        // add2style
        isimage2.classList.remove("hiddenimage");
        isimage2.classList.add("activeimage");
        isText.classList.add("text2color");
      }

      function switchToImage3() {
        // removeotherstyle
        isimage1.classList.remove("activeimage");
        isimage2.classList.remove("activeimage");
        isimage4.classList.remove("activeimage");
        isimage5.classList.remove("activeimage");
        isimage1.classList.add("hiddenimage");
        isimage2.classList.add("hiddenimage");
        isimage4.classList.add("hiddenimage");
        isimage5.classList.add("hiddenimage");
        isText.classList.remove("text1color");
        isText.classList.remove("text2color");
        isText.classList.remove("text4color");
        isText.classList.remove("text5color");
        // add3style
        isimage3.classList.remove("hiddenimage");
        isimage3.classList.add("activeimage");
        isText.classList.add("text3color");
      }

      function switchToImage4() {
        // removeotherstyle
        isimage1.classList.remove("activeimage");
        isimage2.classList.remove("activeimage");
        isimage3.classList.remove("activeimage");
        isimage5.classList.remove("activeimage");
        isimage1.classList.add("hiddenimage");
        isimage2.classList.add("hiddenimage");
        isimage3.classList.add("hiddenimage");
        isimage5.classList.add("hiddenimage");
        isText.classList.remove("text1color");
        isText.classList.remove("text2color");
        isText.classList.remove("text3color");
        isText.classList.remove("text5color");
        // add4style
        isimage4.classList.remove("hiddenimage");
        isimage4.classList.add("activeimage");
        isText.classList.add("text4color");
      }

      function switchToImage5() {
        // removeotherstyle
        isimage1.classList.remove("activeimage");
        isimage2.classList.remove("activeimage");
        isimage3.classList.remove("activeimage");
        isimage4.classList.remove("activeimage");
        isimage1.classList.add("hiddenimage");
        isimage2.classList.add("hiddenimage");
        isimage3.classList.add("hiddenimage");
        isimage4.classList.add("hiddenimage");
        isText.classList.remove("text1color");
        isText.classList.remove("text2color");
        isText.classList.remove("text3color");
        isText.classList.remove("text4color");
        // add5style
        isimage5.classList.remove("hiddenimage");
        isimage5.classList.add("activeimage");
        isText.classList.add("text5color");
      }

      function switchToImage1() {
        // removeotherstyle
        isimage2.classList.remove("activeimage");
        isimage3.classList.remove("activeimage");
        isimage4.classList.remove("activeimage");
        isimage5.classList.remove("activeimage");
        isimage2.classList.add("hiddenimage");
        isimage3.classList.add("hiddenimage");
        isimage4.classList.add("hiddenimage");
        isimage5.classList.add("hiddenimage");
        isText.classList.remove("text2color");
        isText.classList.remove("text3color");
        isText.classList.remove("text4color");
        isText.classList.remove("text5color");
        // add1style
        isimage1.classList.remove("hiddenimage");
        isimage1.classList.add("activeimage");
        isText.classList.add("text1color");
      }
    </script>
  </body>
</html>

If the localStorage is clear (on the first load), the state is like now: all five images are shown, all five images are not active (orange rectangular is not visible) and the colour of this text is default (black).

When user clicks on one of the images, four other images become hidden and only one image with the following number is shown. This text obtains colour of the visible image circle. The same happens on the folllowing clicks. So, images change sequentially (1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, ...) when user clicks on them and this text obtains the same colour as the circle on the image.

The last shown (=active, =current) image and the colour of the text should be stored in the localStorage.

On the page reload current active image and current text colour should be retrieved from the localStorage and shown.

Please, use only vanilla JS, no jQuery, no other libraries or frameworks. It is also important to preserve 5 independant functions (switchToImage2, ... switchToImage5, switchToImage1) for changing these 5 images. Additions to these functions, new necessary functions or necessary editions (new classes, indeces, identificators, whatever) to the code in general are welcomed.

So, everyhing what was described above (instead of localStorage) is working as it should work and the only task is to store state in the localStorage.

Probably it will be necessary to store the whole function in the localStorage. For this purpose this solution may be helpful.

If it is possible, it would be great to preserve the state with only one key in the localStorage. If it is impossible - you are welcomed to create different keys for visible image, its active orange rectangular and text colour.

I hope you will find this challenge interesting!

Could you copypaste my code, edit it and answer with a snippet that will possess all the abovementioned localStorage functionality?

Thank you a lot!

UPD 2023.04.10: the question is still relevant after many hours of multiple tryings... There is also a JSFiddle available at: https://jsfiddle.net/maksymkushnirov/5rkh46ec/1/

  • 4
    You do not store functions in local storage. So what is your attempt at this? When you see yourself copy and pasting the same code over and over again and changing a single line, you should ask yourself, is there a better way? Store the id of the selected image. Use that id to add the class to the element. – epascarello Apr 07 '23 at 13:31
  • 2
    as saying epascarello, you can't store function in local storage. You can store the index you are on, after you use window['switchToImage' + ix] because you want to keep switchToImageX (X: 1,2,3...) – pier farrugia Apr 07 '23 at 14:24
  • UPD 2023.04.10: the question is still relevant after many hours of multiple tryings... There is also a JSFiddle available at: https://jsfiddle.net/maksymkushnirov/5rkh46ec/1/ – maksymkushnirov Apr 10 '23 at 18:36
  • As others said, do not store functions in local storage. About your code: do you really need 5 different functions? The code would be a lot more simple if you had only one function which receives the index and handles the hiding/showing, thus you'd need only to store the index in local storage. – Victor Oliveira Apr 10 '23 at 18:46
  • @VictorOliveira Thank you for replying! Well, I am just a beginner at programming, tha's why I am confused where to put localStorage functions: how to use window['switchToImage' + ix], that was previously mentioned; how to store index, etc. Probably it is really easier to make everything with one function, but then this one function should also switch a colour of a text depending on the colour of a current image and add an orange background to make the current image active. Probably this is all possible but I am stuck. I tried a lot before having finally decided to ask my first quesstion here – maksymkushnirov Apr 10 '23 at 19:16
  • I thought it would be easy just to store active image and execute a corresponding function onload/onreload, but for me it doesn't seem so... – maksymkushnirov Apr 10 '23 at 19:16

1 Answers1

0

Here's one simple way to achieve what you desire. I tried to avoid more advanced constructs such as array methods since you are just beginning at programming and I don't want you to get confuse by it. I also cut the text since you can just replace the placeholder for whatever you desire and to keep this sample shorter.

<!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" />
    <title>Document</title>
    <style>
      .size {
        width: 100px;
        height: 100px;
      }

      .hiddenimage {
        display: none;
      }

      .activeimage {
        background-color: orange;
      }

      .text1color {
        color: green;
      }

      .text2color {
        color: red;
      }

      .text3color {
        color: blue;
      }

      .text4color {
        color: purple;
      }

      .text5color {
        color: brown;
      }
    </style>
  </head>
  <body>
    <div>
      <img
        class="size"
        src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Eo_circle_green_white_number-1.svg"
      />
      <img
        class="size"
        src="https://upload.wikimedia.org/wikipedia/commons/8/85/Eo_circle_red_white_number-2.svg"
      />
      <img
        class="size"
        src="https://upload.wikimedia.org/wikipedia/commons/1/1a/Eo_circle_blue_white_number-3.svg"
      />
      <img
        class="size"
        src="https://upload.wikimedia.org/wikipedia/commons/7/79/Eo_circle_purple_white_number-4.svg"
      />
      <img
        class="size"
        src="https://upload.wikimedia.org/wikipedia/commons/2/28/Eo_circle_brown_white_number-5.svg"
      />
    </div>
    <p class="text">
      Text goes here
    </p>
    <script>
      const sizesElements = document.querySelectorAll(".size");
      const textElement = document.querySelector(".text");
      
      function resetClasses() {
        for (let i = 0; i < sizesElements.length; i++) {
          const element = sizesElements[i];
          element.classList.remove("activeimage");
          element.classList.add("hiddenimage");
          textElement.classList.remove(`text${i + 1}color`);
        }
      }
      
      function showSizeSelector(index) {
        const element = sizesElements[index];
        element.classList.add("activeimage");
        element.classList.remove("hiddenimage");
      }
      
      function styleParagraph(index) {
        textElement.classList.add(`text${index + 1}color`);
      }
      
      function addEventListenerToSizeSelector(element, index) {
        element.addEventListener('click', function() {
          resetClasses(); // will make all 5 size selectors disappear
          showSizeSelector(index); // will make the correct size selector appear
          styleParagraph(index); // adds the correct class to the paragraph
          localStorage.setItem("LSImage", index); // saves the selection to local storage
        })
      }
      
      // Attach "onclick" to each of the size selectors
      for (let i = 0; i < sizesElements.length; i++) {
        addEventListenerToSizeSelector(sizesElements[i], i);
      }
      
      
      const currentImage = localStorage.getItem("LSImage");
      // if on load something is stored in local storage, handle it
      if (currentImage) {
        const currentImageIndex = Number(currentImage); // local storage always stores data as strings
        resetClasses();
        showSizeSelector(currentImageIndex);
        styleParagraph(currentImageIndex);
      }
    </script>
  </body>
</html>

Note that I got rid of onclick on each img tag and instead used the function addEventListener to attach an event handler to a DOM element. You can check more details of this function here. Don't confuse it with addEventListenerToSizeSelector which is a function I declared just to make things more organized.

With that, I can use the same function for every size selector, since the arguments I'm passing to it are different. Finally, I add a check which only will run once (when the script loads), checking if there is any information stored under the "LSImage" key. If there is, note that I use the same functions but passing the information I retrieved to correctly set up the interface to the correct colors.

I don't know if I wasn't clear at some piece of information but feel free to ask for any clarification and happy coding :)

Victor Oliveira
  • 352
  • 2
  • 10