Clicking element affects that element AND a corresponding linked element

Advertisements

I want to click a div, have that div get a class of active AND its corresponding image to show. The two elements are both in separate containers but in order. E.g. clicking div one causes image one to show.

document.addEventListener("DOMContentLoaded", function () {
  const textOption = document.querySelectorAll(".text-option");
  const selectableImage = document.querySelectorAll(".selectable-image")
  function clickedTextOption(clickedOption) {
    textOption.forEach(option => {
      option.classList.remove("active");
    });
    clickedOption.classList.add("active");
  }
  textOption.forEach(option => {
    option.addEventListener("click", () => {
      clickedTextOption(option);
    });
  });
});
.section-2 {
  display: flex;
  background-color: var(--second-background);
  padding: min(100px, 3svw);
  box-sizing: border-box;
  height: 60vh;

  .image-container {
    width: 50svw;
    height: 100%;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    img {
      width: 100%;
      display: block;
      opacity: 0;
    }
    .selectable-image.active {
      opacity: 1;
    }
  }
  .text-selection-container {
    width: 50%;
    display: flex;
    flex-direction: column;
    padding: min(50px, 2svw);
    padding-left: 0;
    .text-option {
      margin: 1svw;
      padding-left: min(50px, 2svw);
      .title {
        font-size: 2svw;
        margin-bottom: 0.5svw;
        font-weight: 700;
      }
      .description {
        font-size: 0.8svw;
        font-weight: 400;
      }
    }

    .text-option.active {
      border-left: 4px solid var(--primary);
      padding-left: calc(min(50px, 2svw) - 4px)
    }
  }
}
<section class="section-2">
        <div class="image-container">
          <img src="https://images.unsplash.com/photo-1700324022450-f143742da6c1?q=80&w=1972&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="" class="selectable-image active">
          <img src="" alt="" class="selectable-image">
          <img src="" alt="" class="selectable-image">
        </div>
        <div class="text-selection-container">
          <div class="text-option active">
            <p class="title">Lorem ipsum dolor sit amet.</p>
            <p class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Iusto recusandae id, nostrum sit sunt facere necessitatibus totam repellat suscipit magni error temporibus placeat expedita, similique ullam facilis sequi, nesciunt asperiores molestiae eius. Minima, voluptates rem esse doloribus eveniet perspiciatis beatae.</p>
          </div>
          <div class="text-option">
            <p class="title">Lorem ipsum dolor sit.</p>
            <p class="description">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quibusdam voluptatibus aspernatur animi porro quis, explicabo hic impedit maiores nisi repudiandae est pariatur quam eos, asperiores laudantium deserunt. Nisi, corrupti? Vitae veritatis repudiandae harum voluptatem.</p>
          </div>
          <div class="text-option">
            <p class="title">Lorem ipsum dolor sit amet consectetur.</p>
            <p class="description">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ad sunt provident quae totam veritatis esse voluptatibus voluptatem. Officia laboriosam explicabo modi ut? Laboriosam dicta iusto perferendis ipsa quis delectus ratione!</p>
          </div>
        </div>
      </section>

I have the function to listen for the click but I don’t know how to then apply to the selectableImage.

Thanks in advance!

>Solution :

Purely for matching the images by index, you can loop through the textOptions with the index parameter added. A shortcut to check if it is the selected option and set an option to (in)active in one go, is by using toggle

document.addEventListener("DOMContentLoaded", function () {
  const textOption = document.querySelectorAll(".text-option");
  const selectableImage = document.querySelectorAll(".selectable-image");
  
  function clickedTextOption(clickedOption) {
    textOption.forEach((option,index) => {
        const active = option.classList.toggle("active", option === clickedOption);
      selectableImage[index].classList.toggle('active', active);
    });    
  }
  
  textOption.forEach(option => {
    option.addEventListener("click", () => {
      clickedTextOption(option);
    });
  });
});
.section-2 {
  display: flex;
  background-color: var(--second-background);
  padding: min(100px, 3svw);
  box-sizing: border-box;
  height: 60vh;

  .image-container {
    width: 50svw;
    height: 100%;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    
  }
  
  .image-container > img {
      width: 100%;
      display: block;
      opacity: 0;
    }
    
   .image-container >    .selectable-image.active {
      opacity: 1;
    }
  
  .text-selection-container {
    width: 50%;
    display: flex;
    flex-direction: column;
    padding: min(50px, 2svw);
    padding-left: 0;
    .text-option {
      margin: 1svw;
      padding-left: min(50px, 2svw);
      .title {
        font-size: 2svw;
        margin-bottom: 0.5svw;
        font-weight: 700;
      }
      .description {
        font-size: 0.8svw;
        font-weight: 400;
      }
    }

    .text-option.active {
      border-left: 4px solid var(--primary);
      padding-left: calc(min(50px, 2svw) - 4px)
    }
  }
}
<section class="section-2">
        <div class="image-container">
          <img src="https://images.unsplash.com/photo-1700324022450-f143742da6c1?q=80&w=1972&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="" class="selectable-image active">
          <img src="" alt="" class="selectable-image">
          <img src="" alt="" class="selectable-image">
        </div>
        <div class="text-selection-container">
          <div class="text-option active">
            <p class="title">Lorem ipsum dolor sit amet.</p>
            <p class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Iusto recusandae id, nostrum sit sunt facere necessitatibus totam repellat suscipit magni error temporibus placeat expedita, similique ullam facilis sequi, nesciunt asperiores molestiae eius. Minima, voluptates rem esse doloribus eveniet perspiciatis beatae.</p>
          </div>
          <div class="text-option">
            <p class="title">Lorem ipsum dolor sit.</p>
            <p class="description">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quibusdam voluptatibus aspernatur animi porro quis, explicabo hic impedit maiores nisi repudiandae est pariatur quam eos, asperiores laudantium deserunt. Nisi, corrupti? Vitae veritatis repudiandae harum voluptatem.</p>
          </div>
          <div class="text-option">
            <p class="title">Lorem ipsum dolor sit amet consectetur.</p>
            <p class="description">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ad sunt provident quae totam veritatis esse voluptatibus voluptatem. Officia laboriosam explicabo modi ut? Laboriosam dicta iusto perferendis ipsa quis delectus ratione!</p>
          </div>
        </div>
      </section>

Leave a ReplyCancel reply