How to link accordion item to external image through JavaScript?

I have this image div container and an accordion side by side. Each accordion item is supposed to be linked to an image.

But I cannot figure out how to create the link between the image and the accordion item.

Here is the HTML structure:

       <div id="accordion__img">
          <img src="img/service_01.jpg" alt="Photography">
          <img src="img/service_02.jpg" alt="Creativity">
          <img src="img/service_03.jpg" alt="Web Design">
        </div>

        <div id="services__accordion">
          <div class="accordion">
            <a href=""><h3 class="photo">Photography</h3></a>
            <div class="accordion__body">
              <p>Lorem ipsum dolor sit amet...</p>
            </div> <!-- /.accordion__body -->
          </div>
          <div class="accordion">
            <a href=""><h3 class="create">Creativity</h3></a>
            <div class="accordion__body">
              <p>Lorem ipsum dolor sit amet...</p>
            </div> <!-- /.accordion__body -->
          </div>
          <div class="accordion">
            <a href=""><h3 class="web">Web Design</h3></a>
            <div class="accordion__body">
              <p>Lorem ipsum dolor sit ame...</p>
            </div> <!-- /.accordion__body -->
          </div>
        </div> <!-- /#services__acordion -->

And here is the JavaScript part for the accordion. I have inserted some code to affect the images:

jQuery(document).ready(function() {
  // Hide all panels
  var panels = $('#services__accordion > .accordion > .accordion__body').hide();

  // Hide all accordion images
  var images = $('#accordion__img > img').hide();

  // Show first panel at start
  panels.first().show();

  // Show first accordion image at start
  images.first().show();

  // On click of a panel title
  $('#services__accordion > .accordion > a > h3').click(function() {
    var $this = $(this);

    // Slide Up all other panels
    panels.slideUp();
    images.slideUp();

    // Slide Down target panel
    $this.parent().next().slideDown();

    return false;
  });
});

At present the accordion works right. But I can’t link them to the images.

Please help me solve this. Thanks in advance.

So I changed your HTML just a little: I gave the images custom id’s, and the panels a custom attribute tab-name. Also, I removed the anchor tags, as the h3 itself can handle a click event, and an anchor with an empty href made my brain cry a little.

That done, I changed your click handler. When the h3 is clicked, it creates a variable called panel, which is different from your $this$this referred to the h3 element, while panel is the accordion element containing that h3. It also gets the tab-name attribute from this panel, and then creates an image variable which is the image with the id tied to this particular panel.

All that done, I simply hide all the panels, hide all the images, show the accordion element for the current panel, and show the linked image.

You can see it working on codePen, or here’s the code:

The HTML:

<div id="accordion-container">
  <div id="accordion__img">
    <img id="photography-img" src="img/service_01.jpg" alt="Photography">
    <img id="creativity-img" src="img/service_02.jpg" alt="Creativity">
    <img id="web-design-img" src="img/service_03.jpg" alt="Web Design">
  </div>

  <div id="services__accordion">
    <div class="accordion" tab-name="photography">
      <h3 class="photo">Photography</h3>
      <div class="accordion__body">
        <p>Lorem ipsum dolor sit amet...</p>
      </div>
      <!-- /.accordion__body -->
    </div>
    <div class="accordion" tab-name="creativity">
      <h3 class="create">Creativity</h3>
      <div class="accordion__body">
        <p>Lorem ipsum dolor sit amet...</p>
      </div>
      <!-- /.accordion__body -->
    </div>
    <div class="accordion" tab-name="web-design">
      <h3 class="web">Web Design</h3>
      <div class="accordion__body">
        <p>Lorem ipsum dolor sit ame...</p>
      </div>
      <!-- /.accordion__body -->
    </div>
  </div>
  <!-- /#services__acordion -->
</div>

and the JS:

$(document).ready(function() {
  // Hide all panels
  let panels = $("#services__accordion > .accordion > .accordion__body").hide();

      // Hide all accordion images
      images = $("#accordion__img > img").hide();

  // Show first panel at start
  panels.first().show();

  // Show first accordion image at start
  images.first().show();

  // On click of a panel title

  $("#services__accordion .accordion  h3").click(function() {
    // The panel is not the H3, but its parent.
    let panel = $(this).parent(),
      // The panel has an attribute that will tell me which image
      //  I want to manipulate. This is because I've given the
      //  images ID's to match. Kind of brittle, but it will work.
      tabName = panel.attr("tab-name"),
      image = $("#" + tabName + "-img");

    // Slide Up all other panels
    panels.slideUp();
    images.slideUp();

    // Slide Down target panel, and target image.
    panel.find(".accordion__body").slideDown();
    image.slideDown();

    return false;
  });
});

1 Like

Thank you, snowmonkey. Thank you very much.

Your rearranging the code makes sense. And yes, the idea of an empty anchor href was quite dumb :laughing: