-1

I’ve been away awhile, but we always come back, won’t we (even if no one missed us;)?

What Am I Trying to Achieve

Basically just images, grouped with a primary image.

This primary will always be shown and also serves as the content for link with a OnClick action.

<a onclick="toggleHidden('ImageGroup1')"><img src="…"></a>

Clicking the image will then trigger the function toggleHidden. This image will be followed by several images that ideally are hidden by default and can be shown when clicking on the primary image of the group. Naturally, only the images following the primary image shall toggle between being displayed or hidden.

What Makes It Harder

I want the title attribute of the image to be dynamic, i.e. has a number that has to be calculated based on the date. I only found this feasible by using JavaScript, meaning I create an image using const imgName = new Image() and then add the attributes and classes. If I put these images into a <div> or <span> element, give it an id and use element.getElementById in my function toggleHidden, then the images are still shown. (Btw, I made it work with ordinary images, that is images that a created using HTML code like <img src="">.)

In Theory

I tried two functions. First, all images in the same group have the same class (here ImageGroup1).

1st function:

function showHiddenClassElements(myClassName) {
    var hidimg = document.getElementsByClassName(myClassName);
    if (hidimg.style.display === "none") {
        hidimg.style.display = "block";
    } else {
        hidimg.style.display = "none";
    }
}

I tried several variations, using an inversion like !== "none" (and corresponding changes in the code) and different attributes than initial or inline.

2nd function:

function toggleHiddenClass(myClassName) {
    var element = document.getElementsByClassName(myClassName);
    element.classList.toggle("hiddenspan");
}

…where hiddenspan contains only display: none; - nothing works.

My Code

<style>
    .Group2 { }

    .Group3 { }

    .basic {
        width:150px;
        height:225px;
    }

    .hiddenspan {
        display: none;
    }
</style>

<script>
    function myFunction(myDIVid) {
        var x = document.getElementById(myDIVid);
        if (x.style.display === "none") {
            x.style.display = "block";
        } else {
            x.style.display = "none";
        }
    }

    function showHiddenClassElements(myClassName) {
        var hidimg = document.getElementsByClassName(myClassName);
        if (hidimg.style.display === "none") {
            hidimg.style.display = "block";
        } else {
            hidimg.style.display = "none";
        }
    }

    function toggleHiddenClass(myClassName) {
        var element = document.getElementsByClassName(myClassName);
        element.classList.toggle("hiddenspan");
    }
</script>

<body>
    <h2>Group 1</h2>

    <a onclick="myFunction('Group1')"><img class="basic" src="01.gif" alt="01" title="01"></a>
    <span id="Group1" class="hiddenspan">
        <img class="basic" src="001.jpeg" alt="001" title="001">
        <img class="basic" src="002.jpeg" alt="002" title="002">
        <img class="basic" src="003.jpeg" alt="003" title="003">
    </span>

    <h2>Group 2</h2>

    <a onclick="showHiddenClassElements('Group2')">
      <img class="basic" src="02.gif" alt="02" title="02">
    </a>

    <script>
        var d1 = new Date(1994,1,31);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img02_001 = new Image();
        img02_001.src = "02/001.jpeg"; 
        img02_001.classList.add("basic"); 
        img02_001.classList.add("Group2");
        img02_001.alt="001";
        img02_001.title="001 ("+Math.floor(daydiff)+" years old)";
        document.body.appendChild(img02_001);
    </script>

    <script>
        var d1 = new Date(2006,7,23);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img02_002 = new Image();
        img02_002.src = "02/002.jpeg"; 
        img02_002.classList.add("basic"); 
        img02_002.classList.add("Group2");
        img02_002.alt="002";
        img02_002.title="002 ("+Math.floor(daydiff)+" years old)"; 
        document.body.appendChild(img02_002);
    </script>

    <h2>Group 3</h2>

    <a onclick="showHiddenClassElements('Group3')">
        <img class="basic" src="03.gif" alt="03" title="03">
    </a>

    <script>
        var d1 = new Date(1997,3,31);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img03_001 = new Image();
        img03_001.src = "03/001.jpeg"; 
        img03_001.classList.add("basic"); 
        img03_001.classList.add("Group3");
        img03_001.alt="001";
        img03_001.title="001 ("+Math.floor(daydiff)+" years old)"; 
        document.body.appendChild(img03_001);
    </script>

    <script>
        var d1 = new Date(2016,10,23);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img03_002 = new Image();
        img03_002.src = "03/002.jpeg"; 
        img03_002.classList.add("basic"); 
        img03_002.classList.add("Group3");
        img03_002.alt="002";
        img03_002.title="002 ("+Math.floor(daydiff)+" years old)"; 
        document.body.appendChild(img03_002);
    </script>

    <h2>Group 4</h2>

    <a onclick="myFunction('Group4')">
        <img class="basic" src="03.gif" alt="03" title="03">
    </a>

    <span id="Group4" class="hiddenspan">

        <script>
            var d1 = new Date(1997,3,31);
            var d2 = new Date();
            var diff = d2.getTime() - d1.getTime();
            var daydiff = (diff / 31557600000);
            const img03_001 = new Image();
            img03_001.src = "03/001.jpeg"; 
            img03_001.classList.add("basic"); 
            img03_001.classList.add("Group3");
            img03_001.alt="001";
            img03_001.title="001 ("+Math.floor(daydiff)+" years old)";
            document.body.appendChild(img03_001);
        </script>

        <script>
            var d1 = new Date(2016,10,23);
            var d2 = new Date();
            var diff = d2.getTime() - d1.getTime();
            var daydiff = (diff / 31557600000);
            const img03_002 = new Image();
            img03_002.src = "03/002.jpeg"; 
            img03_002.classList.add("basic"); 
            img03_002.classList.add("Group3");
            img03_002.alt="002";
            img03_002.title="002 ("+Math.floor(daydiff)+" years old)";
            document.body.appendChild(img03_002);
        </script>
    </span>
</body>

Obviously the code has been simplified, especially the HTML part (no <h1> header, no HTML declaration), but you should get the idea.

For Group 1 the code works flawlessly (almost, except for a line break after the primary image, but I could live with that), the same function with images generated with JavaScript (Group 4) will display the images, as if the <span> element with its id and class weren’t even there.

The other functions for group 2 and 3 do not work at all, as if getElementsByClassName doesn’t work at all. That's what I believe.

So what do you think? Is there a way to toggle the display of these images?

Edit 1

As Mike 'Pomax' Kamermans suggested, I added an event listener (hopefully the right way):

<script>
    document.getElementById("idGroup3").addEventListener("click", toggleHiddenClass("Group3"));
</script>

…and changed the code for Group 3 like this (per suggestion):

<h2>Group 3</h2>

<button id="idGroup3">
    <img class="basic" src="03.gif" alt="03" title="03">
</button>

<script>
    var d1 = new Date(1997,3,31);
    var d2 = new Date();
    var diff = d2.getTime() - d1.getTime();
    var daydiff = (diff / 31557600000);
    const img03_001 = new Image();
    img03_001.src = "03/001.jpeg"; 
    img03_001.classList.add("basic"); 
    img03_001.classList.add("Group3");
    img03_001.alt="001";
    img03_001.title="001 ("+Math.floor(daydiff)+" years old)";
    document.body.appendChild(img03_001);
</script>

<script>
    var d1 = new Date(2016,10,23);
    var d2 = new Date();
    var diff = d2.getTime() - d1.getTime();
    var daydiff = (diff / 31557600000);
    const img03_002 = new Image();
    img03_002.src = "03/002.jpeg"; 
    img03_002.classList.add("basic"); 
    img03_002.classList.add("Group3");
    img03_002.alt="002";
    img03_002.title="002 ("+Math.floor(daydiff)+" years old)"; 
    document.body.appendChild(img03_002);
</script>

Still no effect.

midnight-coding
  • 2,857
  • 2
  • 17
  • 27

1 Answers1

1

Here's my solution.

The problem was neither button nor the event listener (though it certainly is a more proper solution with both) but the question how to iterate the HTMLCollection returned by getElementsByClassName.

Identifying this as the cause of my problem took some testing (thanks to the Google Chrome DevTools). And the first step to the full solution can be found here. The second part came from the German website mediaevent.de, with some help from here for a better understanding of the code.

<html>

<head>

<style>
.basic {
width:150px;
height:225px;
}

.button {
  background-color: rgba(0, 0, 0, 0);
  border: none;
  color: rgba(0, 0, 0, 0);
  text-decoration: none;
  display: inline;
  padding: 0;
  cursor: pointer;
}

.hiddenspan {
  display: none;
}
</style>

<script>
function functionButton(className) {
    Array.from(document.getElementsByClassName(className))
    .forEach((element) => element.classList.toggle("hiddenspan"));
}
</script>

</head>
<body>

<h2>Group 1</h2>

<button class="button" id="buttonGroup1"><img class="basic" src="01.gif" alt="01" title="01"></button>
<img class="basic imgGroup1 hiddenspan" src="01/001.jpeg" alt="01: 001" title="01: 001">
<script>
        var d1 = new Date(1994,1,31);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img01_002 = new Image();
        img01_002.src = "01/002.jpeg"; 
        img01_002.classList.add("basic");
        img01_002.classList.add("imgGroup1");
        img01_002.classList.add("hiddenspan");
        img01_002.alt="01: 002";
        img01_002.title="01: 002 ("+Math.floor(daydiff)+" years old)";
        document.body.appendChild(img01_002);
    </script>

<script>
const elementButtonGroup1 = document.getElementById("buttonGroup1");
elementButtonGroup1.addEventListener("click", function() {
    functionButton("imgGroup1");
    }, false
    );
</script>

<h2>Group 2</h2>

<button class="button" id="buttonGroup2"><img class="basic" src="02.gif" alt="02" title="02"></button>
<img class="basic imgGroup2 hiddenspan" src="02/002.jpeg" alt="02: 001" title="02: 001">
<script>
        var d1 = new Date(2016,10,23);
        var d2 = new Date();
        var diff = d2.getTime() - d1.getTime();
        var daydiff = (diff / 31557600000);
        const img02_002 = new Image();
        img02_002.src = "02/002.jpeg"; 
        img02_002.classList.add("basic");
        img02_002.classList.add("imgGroup1");
        img02_002.classList.add("hiddenspan");
        img02_002.alt="02: 002";
        img02_002.title="02: 002 ("+Math.floor(daydiff)+" years old)";
        document.body.appendChild(img02_002);
    </script>

<script>
const elementButtonGroup2 = document.getElementById("buttonGroup2");
elementButtonGroup2.addEventListener("click", function() {
    functionButton("imgGroup2");
    }, false
    );
</script>

</body>
</html>

Working with buttons, you need to add a specific script for each button, then add an event listener to the aforementioned button. And this code can be simplified like this:

<script>
document.getElementById("buttonGroup1").addEventListener("click", function() {
    functionButton("imgGroup1");
    }, false
    );
</script>

It works on both kinds of images. In this example, the images are hidden by default.

By the way, even if a button is the better solution, it does worked with <a onclick="functionButton('imgGroup1')"><img class="basic" src="01.gif" alt="01" title="01"></a> instead of <button class="button" id="buttonGroup1"><img class="basic" src="01.gif" alt="01" title="01"></button> (and without the script to add an event listener to each button and without the need to style the button).