Search code examples
javascriptcssbuttonstatic

Trouble with a single ON/OFF type button in Javascript


I'll preface this by saying that I'm trying to learn JS.

I'm currently trying to make a button that hides GIFs (or other moving images) when clicked, then changes to a "show GIFs" button until clicked again.

So the button needs to do 2 things:

  1. Hide/show all images of a certain class, choosing correctly based on their current display status
  2. Switch which button it is on use

I have figured out the first part on its own, but I can't figure out the second effectively.

I'm also not sure how to approach the button changing? I was thinking about having 2 buttons on the page and using relative + absolute positioning to have the buttons overlay each other, and just switch which class of button is visible tied to their respective functions, but if there's a better way to do that by all means correct me. I did see a solution on here using an input as a button for ease of switching, but I've also read that its bad practice to use an input when you could use a button? If thats outdated though just let me know.

Here's the JS that successfully hid images on click:

var x = document.getElementsByClassName('flash');
function hide() {
  for(var i=0; i<x.length; i++) {
    x[i].style.display = 'none';
    }
}
function show() {
  for(var i=0; i<x.length; i++) {
    x[i].style.display = 'block';
    }
}

Here's where I hit a wall trying to combine things:

var imagesHidden = false;
var myBtn = document.getElementById("gifTog");
myBtn.onclick = function togGIF(){
      var images = Array.from(document.getElementsByClassName("flash"));
      if(imagesHidden){
            imagesHidden = false;
            images.forEach(function(img){
               img.style.display = "block";
            });
            myBtn.Element.className = "hide";
      } else {
            imagesHidden = true;
            images.forEach(function(img){
               img.style.display = "none";
            });
            myBtn.Element.className = "show";
      }
};

& here's the page I'm testing it: https://ooops.lol/testing/test

Honestly I was half expecting it not to work because I am horrible at parsing JS, and this is the most complicated function I've tried to tackle. I asked for help elsewhere and that is where the second chunk of code came from, I would not be surprised if I just made a mistake changing some things or explained my goal poorly.

Any help is appreciated!


Solution

  • In step #2 you don't reuse the code from step #1. A big no no. Try to organize into functions.

    I also added a generic function to toggle button text between 2 states.

    It makes sense to change state of variable imagesHidden inside the respective show and hide functions.

    var imagesHidden = false;
    var x = document.querySelectorAll('.flash');
    var myBtn = document.getElementById("gifTog");
    
    function hide() {
      imagesHidden = true
      for (var i = 0; i < x.length; i++) {
        x[i].style.display = 'none';
      }
      console.log ("gifs are now hidden")
    }
    
    function show() {
      imagesHidden = false
      var x = document.querySelectorAll('.flash');
      for (var i = 0; i < x.length; i++) {
        x[i].style.display = 'block';
      }
      console.log ("gifs are now shown")
    }
    
    function alternateButtonText(btn) {
      var current = btn.innerText
      btn.innerText = btn.getAttribute("data-alt-text")
      btn.setAttribute("data-alt-text", current)
    }
    
    myBtn.onclick = function togGIF() {
      alternateButtonText(myBtn)
      if (imagesHidden) {
        show()
      } else {
        hide()
      }
    };
    <button id="gifTog" data-alt-text="show GIFs">hide GIFs</button>