Hiding and Showing multiple pictures html element on button click and depending on focused button?

Hi everyone .I’m quite new at Javascript/Jquery and I have a decent HTML and CSS background. Here is my problem. I have a layout with 3 buttons corresponding to 6 GIF images possibilities depending on actual focused button and 3 texts corresponding to the 3 buttons . When clicking on one of the three buttons, to display the right GIF and right text, code has to check actual focused button and pick one of 2 img wrapped in 2 different picture elements with dedicated classes.

To do so, I called Jquery function and wrote an .on(‘click’, function() {…}) containing an if…else if statement without else . The problem is that it works but not completely, only the if is displaying when clicking on proper button although there are 2 possibilities per if…else if statement corresponding to 2 different GIF images. By the way those GIF are not heavy (each one less than 1 Mo).

After checking in many websites (including Stack Overflow) during hours and hours if not days I still can’t make it work. I tried to change selectors : to use (":focus")** , to add **tabindex** attribute to buttons...and so on! Even Classic Javascript **( document.activeElement ) solution does not work, with it it’s worse : nothing happens on buttons click. No problem with texts because they are the same in each if…else if statement .

Here is an extract of my HTML :


<div class="images-gif">
    
    <!--  --------GIF BUTTON 1------------->
            
    <!--Possibility 1-->
            
    <picture class="btn1-pos1"> 
                        
    <source class="btn1-pos1"
        media="(orientation: landscape)"
        srcset="images/GIF/danse-deb1_1920.gif 1920w,
                images/GIF/danse-deb1_1440.gif 1440w,
                images/GIF/danse-deb1_960.gif 960w,
                images/GIF/danse-deb1_800.gif 800w,
                images/GIF/danse-deb1_600.gif 600w"
        sizes="100vw">
                                       
                        
     <source class="btn1-pos1"
         media="(orientation: portrait)"
         srcset="images/GIF/danse-deb1_portrait_600.gif 600w,
                 images/GIF/danse-deb1_480.gif 480w,
                 images/GIF/danse-deb1_320.gif 320w"
         sizes="100vw">
                        
     <img src="images/GIF/danse-deb1_1920.gif" class="btn1-pos1" width="710" height="600" alt="dance 1"/>
                    
    </picture>
            
            
    <!--Possibility 2-->
            
    <picture class="btn1-pos2"> 
                        
        <source class="btn1-pos2"
                media="(orientation: landscape)"
                srcset="images/GIF/danse-deb2_1920.gif 1920w,
                        images/GIF/danse-deb2_1440.gif 1440w,
                        images/GIF/danse-deb2_960.gif 960w,
                        images/GIF/danse-deb2_800.gif 800w,
                        images/GIF/danse-deb2_600.gif 600w"
                sizes="100vw" >
                        
        <source class="btn1-pos2"
                media="(orientation: portrait)"
                srcset="images/GIF/danse-deb2_portrait_600.gif 600w,
                        images/GIF/danse-deb2_480.gif 480w,
                        images/GIF/danse-deb2_320.gif 320w"
                sizes="100vw" >
                        
        <img src="images/GIF/danse-deb2_1920.gif" class="btn1-pos2" width="710" height="600" alt="dance 2"/>
            
    </picture>
                
            
    <!--  --------GIF BUTTON 2------------->
            
            
    <!--Possibility 1-->
            
    <picture class="btn2-pos1"> 
            
        <source class="btn2-pos1"
                media="(orientation: landscape)"
                srcset="images/GIF/danse-inter1_1920.gif 1920w,
                images/GIF/danse-inter1_1440.gif 1440w,
                images/GIF/danse-inter1_960.gif 960w,
                images/GIF/danse-inter1_800.gif 800w,
                images/GIF/danse-inter1_600.gif 600w"
                sizes="100vw">
                                       
                        
        <source class="btn2-pos1"
                media="(orientation: portrait)"
                srcset="images/GIF/danse-inter1_portrait_600.gif 600w,
                        images/GIF/danse-inter1_480.gif 480w,
                        images/GIF/danse-inter1_320.gif 320w"
                sizes="100vw">
                        
     <img src="images/GIF/danse-inter1_1920.gif" class="btn2-pos1" width="710" height="600" alt="dance 3"/>
                   
     </picture>
                 
     <!--Possibility 2-->
            
    <picture class="btn2-pos2"> 
                    
        <source class="btn2-pos2"
                media="(orientation: landscape)"
                srcset="images/GIF/danse-inter2_1920.gif 1920w,
                        images/GIF/danse-inter2_1440.gif 1440w,
                        images/GIF/danse-inter2_960.gif 960w,
                        images/GIF/danse-inter2_800.gif 800w,
                        images/GIF/danse-inter2_600.gif 600w"
                sizes="100vw">

        <source class="btn2-pos2"
                media="(orientation: portrait)"
                srcset="images/GIF/danse-inter2_portrait_600.gif 600w,
                        images/GIF/danse-inter2_480.gif 480w,
                        images/GIF/danse-inter2_320.gif 320w"
                sizes="100vw">

    <img src="images/GIF/danse-inter2_1920.gif" class="btn2-pos1" width="710" height="600" alt="dance 4"/>

    </picture>

            
         <!--  --------GIF BUTTON 3------------->
            
            
          <!--Possibility 1-->
            
    <picture class="btn3-pos1"> 

        <source class="btn3-pos1"
                media="(orientation: landscape)"
                srcset="images/GIF/danse-av1_1920.gif 1920w,
                images/GIF/danse-av1_1440.gif 1440w,
                images/GIF/danse-av1_960.gif 960w,
                images/GIF/danse-av1_800.gif 800w,
                images/GIF/danse-av1_600.gif 600w"
                sizes="100vw">
                                       
                        
       <source class="btn3-pos1"
               media="(orientation: portrait)"
               srcset="images/GIF/danse-av1_portrait_600.gif 600w,
                       images/GIF/danse-av1_480.gif 480w,
                       images/GIF/danse-av1_320.gif 320w"
               sizes="100vw">
                        
    <img src="images/GIF/danse-av1_1920.gif" class="btn3-pos1" width="710" height="600" alt="dance 5"/>
                    
    </picture>
                  

            
            <!--Possibility 2-->

    <picture class="btn3-pos2"> 
                        
      <source class="btn3-pos2"
              media="(orientation: landscape)"
              srcset="images/GIF/danse-av2_1920.gif 1920w,
                      images/GIF/danse-av2_1440.gif 1440w,
                      images/GIF/danse-av2_960.gif 960w,
                      images/GIF/danse-av2_800.gif 800w,
                      images/GIF/danse-av2_600.gif 600w"
                      sizes="100vw">

       <source class="btn3-pos2"
               media="(orientation: portrait)"
               srcset="images/GIF/danse-av2_portrait_600.gif 600w,
               images/GIF/danse-av2_480.gif 480w,
               images/GIF/danse-av2_320.gif 320w"
               sizes="100vw">

    <img src="images/GIF/danse-av2_1920.gif" class="btn3-pos2" width="710" height="600" alt="dance 6"/>
                        
            
            
    </picture>
                    
    <div class="btn-group">
     <button type="button" id="btn-1" tabindex="1" autofocus>FIRST</button>
     <button type="button" id="btn-2" tabindex="2">SECOND</button>
     <button type="button" id="btn-3" tabindex="3">THIRD</button>
    </div>


</div>

And here is Javascript/Jquery corresponding code :


$(function() { 

 $("#btn-2").on("click", function()  {

                 if($("#btn-1:focus")) {
                    $(".btn1-pos1").hide();
                    $(".btn1-pos2").hide();
                    $(".btn2-pos2").hide();
                    $(".btn3-pos1").hide();
                    $(".btn3-pos2").hide();
                    $(".btn2-pos1").show();
                    $(".txt-1").hide();
                    $(".txt-3").hide();
                    $(".txt-2").show(1200);
                    
              } else if($("#btn-3:focus")) {
                    $(".btn1-pos1").hide();
                    $(".btn1-pos2").hide();
                    $(".btn3-pos1").hide();
                    $(".btn3-pos2").hide();
                    $(".btn2-pos1").hide();
                    $(".btn2-pos2").show();
                    $(".txt-1").hide();
                    $(".txt-3").hide();
                    $(".txt-2").show(1200);
                    
             }   ;    
         }) ;

    
    
      // ---------------------------------------------------------------------
  

    
        $("#btn-1").on("click", function()  {
              if($("#btn-3:focus")) {
                 $(".btn3-pos1").hide();
                 $(".btn3-pos2").hide();
                 $(".btn2-pos1").hide();
                 $(".btn2-pos2").hide();
                 $(".btn1-pos2").hide();
                 $(".btn1-pos1").show();
                 $(".txt-3").hide();
                 $(".txt-2").hide();
                 $(".txt-1").show(1200);
                 
                 
           } else if($("#btn2:focus)) {
                 $(".btn3-pos1").hide();
                 $(".btn3-pos2").hide();
                 $(".btn2-pos1").hide();
                 $(".btn2-pos2").hide();
                 $(".btn1-pos1").hide();
                 $(".btn1-pos2").show();
                 $(".txt-2").hide();
                 $(".txt-3").hide();
                 $(".txt-1").show(1200);                
            
           }       ;    
            
            } )  ;
         


       // --------------------------------------------------------------------
    
    
    
    
        
        
        
            $("#btn-3").on("click", function()  {
                if($("#btn-2:focus")) {
                    $(".btn1-pos1").hide();
                    $(".btn1-pos2").hide();
                    $(".btn2-pos1").hide();
                    $(".btn2-pos2").hide();
                    $(".btn3-pos2").hide();
                    $(".btn3-pos1").show();
                    $(".txt-2").hide();
                    $(".txt-1").hide();
                    $(".txt-3").show(1200);
                    
                    
              } else if($("#btn-1:focus"))  {
                    $(".btn1-pos1").hide();
                    $(".btn1-pos2").hide();
                    $(".btn2-pos1").hide();
                    $(".btn2-pos2").hide();
                    $(".btn3-pos1").hide();
                    $(".btn3-pos2").show();
                    $(".txt-2").hide();
                    $(".txt-1").hide();
                    $(".txt-3").show(1200);
                    
             }     ;
                

            }) ;

    
})


So, what am I doing wrong? Is it an **if...else if** statement syntax error? Can I change something in HTML? Or make it work in a shorthand code using Javascript/Jquery? Problem seems to be the if...else if statement as it only considers "if" and not "else if". Text changes, GIF images too but not with the 2 possibilities only possibility of "if" and never considers the "else if" code. Is it a **picture** element tricky thing that I'm not aware about? Still don't know after many researches.

If someone can help me it would be a very kind help. **Thank you so much!** *I'm mad not accomplish it by myself* . I hope one day, soon, I will help this amazing community!

Gerard

Bearing in mind my JS is pretty basic as well I don’t see why you are testing for focus and then your else statement is an exact duplicate of the if statement. If you are going to do the same thing whatever the outcome then you may as well just do it without the if statement.

e.g.

$(function () {
  $("#btn-2").on("click", function () {
    $(".btn1-pos1").hide();
    $(".btn1-pos2").hide();
    $(".btn2-pos2").hide();
    $(".btn3-pos1").hide();
    $(".btn3-pos2").hide();
    $(".btn2-pos1").show();
    $(".txt-1").hide();
    $(".txt-3").hide();
    $(".txt-2").show(1200);
  });

  // ---------------------------------------------------------------------

  $("#btn-1").on("click", function () {
    $(".btn3-pos1").hide();
    $(".btn3-pos2").hide();
    $(".btn2-pos1").hide();
    $(".btn2-pos2").hide();
    $(".btn1-pos2").hide();
    $(".btn1-pos1").show();
    $(".txt-3").hide();
    $(".txt-2").hide();
    $(".txt-1").show(1200);
  });

  // --------------------------------------------------------------------

  $("#btn-3").on("click", function () {
    $(".btn1-pos1").hide();
    $(".btn1-pos2").hide();
    $(".btn2-pos1").hide();
    $(".btn2-pos2").hide();
    $(".btn3-pos2").hide();
    $(".btn3-pos1").show();
    $(".txt-2").hide();
    $(".txt-1").hide();
    $(".txt-3").show(1200);
  });
});

(Note you had a missiing closing quote in your code here else if ($("#btn2:focus)) )

Also that code is duplicating a lot of things and you could do it all in one routine. You’d apply a click handler to all the buttons (using a class) and then when a button is clicked you just hide everything else apart from the items you want. You could use a data attribute on the button to supply the data for the destination you want shown and retrieve that in the js routine. I’ll leave that for the experts to chime in :slight_smile:

[edit]
Actually I see now that you are changing something different in the else section that wan’t clear from the confusing code.

What you should do is hide all the common items first and then do the if then statement check for the two different items and the code will be easier to read.

Note that your if statement will always evaluate to true and is not detecting if the element has focus.

Lastly, when you click a button the button you clicked will have focus so there’s no point in checking if some other button has a focus. If you want to detect which button was last clicked then you should dynamically add a class to it (.active for example) and then you can check which one was active when a button was clicked and then remove the class and add it to the currently clicked button
[/edit]

1 Like

I think this is what you are roughly trying to do but the code is repetitive and I’m sure the JS gurus here could greatly simplify it.

Note that you don’t define what should happen by default on page load as all will show. You need to build that into your routine also.

I still can’t quite see the logic of showing different items when a button is clicked depending on what button was clicked before. It seems confusing that for example clicking button 2 will show a different image depending if you are coming from button 1 or button3?

1 Like

Taking the code from the pen, I had a look if I could remove the repetition.
The best I came up with was this (which is awful):

function getButtons(num) {
  switch (num) {
    case '1': return [3, 2];
    case '2': return [1, 3];
    case '3': return [2, 1];
  }
}

$('button[id^="btn-"').on('click', function handleButtonClick() {
  if ($(this).hasClass('active')) return;

  const clicked = this.id.replace('btn-', '');
  const buttons = getButtons(clicked);

  $('.pic').hide();
  $('.txt').hide();
  $(`.txt-${clicked}`).show(1200);

  if ($(`#btn-${buttons[0]}`).hasClass('active')) {
    $(`.btn${clicked}-pos1`).show();
  } else if ($(`#btn-${buttons[1]}`).hasClass('active')) {
    $(`.btn${clicked}-pos2`).show();
  }

  $('.btn-group button').removeClass('active');
  $(this).addClass('active');
});

The problem is that the showing/hiding of elements depending on what is clicked is rather random.
If this were me, I’d sit back and think about what I want to show/hide when, then try to restructure the markup to make the logic in the JS file cleaner. Perhaps think about using data attributes?

To be clear - don’t use this solution. I was about to bin it, but thought it might highlight where the repetition is occurring :slight_smile:

3 Likes

Yeah, such relations probably shouldn’t be hard-coded in the JS logic. IMO a good option for something like this are always data attributes (simplified for the general concept here):

<button 
  data-show=".text-1, .text-2" 
  data-hide=".text-3">
  Button One
</button>

<button 
  data-show=".text-3" 
  data-hide=".text-1, .text-2">
  Button Two
</button>

<p class="text-1" hidden>foo</p>
<p class="text-2" hidden>bar</p>
<p class="text-3" hidden>baz</p>
$('button').on('click', function () {
  $(this.dataset.show).show()
  $(this.dataset.hide).hide()
})

By specifying the relations in the markup alone, the JS won’t require adjustment when the markup changes.

3 Likes

Dear Paul,
Thank you so much for your reply.

Dear Paul,
Thank tou, your codePen is exactly what I’m trying to do.
The logic is simple : Each GIF image is the following of the other depending on which button focus was previously. GIF images are sequels of one each other. The point behind that is that I’m creating 3 levels for dance hobby : each time you click on a level (starter - intermediate - advanced) there’s a specific animation that is related to the previous one depending on previous button click. I’m going to try your solution and give you a feedback asap. Thank you again for your kind help.
Gerard

1 Like

Dear James,
Thank you for your sweet help. You understood exactly what my help demand was about, that’s it. I’m going to try your solution too and give you a feedback asap. Thanks !!
Gerard

Hey m3g4p0p !
Thank you for your reply and kind help. I’m going to try that too and give a feedback. Excellent ! I’m so glad to find help in Javascript/Jquery, what a nice community. I hope I will help others soon.

Gerard

2 Likes

Yes that’s basically what I hinted at in my first post.

Each button will require 2 different sets of data attributes to be present on each button. Then you’d need to determine which of the data attributes you would use depending on which button was previously active.

It would avoid the need for storing that data in the js.

I’m still not sure I understand the ‘use case’ though :slight_smile:

2 Likes

Paul,
First focused text(1) and GIF image (1) are in “display : block” and the others on “display : none” in CSS.
So your codePen is nearly exact, at first sight you only see the text 1 and GIF image 1.
After clicking, each button has 2 possibilities of animated GIF and a unique text corresponding to it. For example : if you click on button 2 (intermediate Level) from button 1 (starter Level) or from button 3 (advanced Level) the transition of animation is not the same. That’s the reason why each button has 2 GIF images possibilities. I don’t know if the ‘use case’ is now more clear for you.

1 Like