Home > Back-end >  The client.Height function in conjunction with the forEach method JS
The client.Height function in conjunction with the forEach method JS

Time:03-07

I have an accordion list and my task was to implement a smooth tabs open/close function for dynamic content without a set height. The forEach method works perfectly.

The smooth open/close function (setHeight in JS snippet)also works fine, but only for the first tab.

In other tabs this function does not work and the opening does not happen as we would like it to. I've already racked my brains. How can I combine the forEach method and the "setHeight" function so that nothing breaks?

const accItems = document.querySelectorAll('.accordion__item');

accItems.forEach((item) => {
  const icon = item.querySelector('.accordion__icon');
  const content = item.querySelector('.accordion__content');

  item.addEventListener('click', () => {
    if (item.classList.contains('open')) {
      item.classList.remove('open');
      icon.classList.remove('open');
      content.classList.remove('open');

    } else {
      const accOpen = document.querySelectorAll('.open');
      accOpen.forEach((open) => {
        open.classList.remove('open');
      });

      item.classList.add('open');
      icon.classList.add('open');
      content.classList.add('open');
    }
    setHeight();
  });
});

function setHeight() {
  let contentWrapper = document.getElementById('content__wrapper');
  if (contentWrapper.clientHeight) {
    contentWrapper.style.height = 0;
  } else {
    let accText = document.querySelector('.acc-text');
    contentWrapper.style.height = accText.clientHeight   "px";
  }
}
body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  color: #1f1f1f;
  background: #f2f2f2;
}

html {
  font-size: 62.5%;
}

h5 {
  margin: 0;
}

p {
  margin: 0;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: auto;
  max-width: 140rem;
}

.section-accordion {
  display: flex;
  align-items: center;
  max-width: 134rem;
  margin: auto;
}

.accordion-image {
  width: 630px;
  height: 450px;
  background: url("https://eternel.maitreart.com/wp-content/uploads/2021/07/creat-home-1.jpg");
  background-repeat: no-repeat;
  background-size: cover;
}

.accordion {
  width: 63rem;
  height: auto;
  margin-left: 8rem;
}

.accordion__item {
  border-top: 1px solid #a8a6a4;
  overflow: hidden;
  transition: height .5s;
  padding-bottom: 1rem;
}

.accordion__item:last-child {
  border-bottom: 1px solid #a8a6a4;
}

.accordion__item--header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2rem 1rem 1rem 1rem;
  cursor: pointer;
}

.accordion__item.open {
  width: 100%;
}

.accordion__title {
  font-family: 'Lora';
  font-size: 2.4rem;
  line-height: 1.2;
  font-weight: 400;
  text-transform: uppercase;
}

.accordion__icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 2rem;
  height: 2rem;
  transition: transform .5s ease;
}

.accordion__icon span:first-child {
  transform: rotate(90deg) translateX(1px);
  width: 1.4rem;
  height: .1rem;
  background: currentColor;
}

.accordion__icon span {
  display: block;
  width: 1.4rem;
  height: .1rem;
  background: currentColor;
  cursor: pointer;
}

.accordion__icon.open {
  transform: rotate(45deg);
}

.accordion__content {
  font-family: 'Roboto', sans-serif;
  font-size: 1.6rem;
  line-height: 1.62;
  font-weight: 400;
  padding: 0 1rem 0 1rem;
  height: 0;
  transition: height .5s;
  overflow: hidden;
}

.accordion__content.open {
  margin-bottom: 1.2rem;
  height: 100%;
}
<div >
  <section >
    <div ></div>
    <div >
      <div >
        <div >
          <h5 >Visual direction</h5>
          <div >
            <span></span>
            <span></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Event production</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Brand creation</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Design concept</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
    </div>
</div>
</section>
</div>

CodePudding user response:

An element's id needs to be unique. I would change id to class, and then pass the item to setHeight()

setHeight(item);

then get the item's content wrapper:

function setHeight(item) {
  let contentWrapper = item.querySelector('.content__wrapper');
  if (contentWrapper.clientHeight) {
    contentWrapper.style.height = 0;
  } else {
    let accText = item.querySelector('.acc-text');
    contentWrapper.style.height = accText.clientHeight   "px";
  }
}

CodePudding user response:

It does not seem that you need setHeight which is the one that messes the display

Here is a delegated version

const accordionItems = document.querySelectorAll(".accordion__item");
document.querySelector('.accordion').addEventListener('click', (e) => {
  const item = e.target.closest(".accordion__item");
  if (!item) return
  accordionItems.forEach(acItem => {
    if (acItem !== item) {
      acItem.classList.remove('open');
      acItem.querySelector('.accordion__icon').classList.remove('open');
      acItem.querySelector('.accordion__content').classList.remove('open');
    }
  });
  
  const icon = item.querySelector('.accordion__icon');
  const content = item.querySelector('.accordion__content');
  item.classList.toggle("open")
  const isOpen = item.classList.contains("open");
  icon.classList.toggle("open", isOpen);
  content.classList.toggle('open', isOpen);
});
body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  color: #1f1f1f;
  background: #f2f2f2;
}

html {
  font-size: 62.5%;
}

h5 {
  margin: 0;
}

p {
  margin: 0;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: auto;
  max-width: 140rem;
}

.section-accordion {
  display: flex;
  align-items: center;
  max-width: 134rem;
  margin: auto;
}

.accordion-image {
  width: 630px;
  height: 450px;
  background: url("https://eternel.maitreart.com/wp-content/uploads/2021/07/creat-home-1.jpg");
  background-repeat: no-repeat;
  background-size: cover;
}

.accordion {
  width: 63rem;
  height: auto;
  margin-left: 8rem;
}

.accordion__item {
  border-top: 1px solid #a8a6a4;
  overflow: hidden;
  transition: height .5s;
  padding-bottom: 1rem;
}

.accordion__item:last-child {
  border-bottom: 1px solid #a8a6a4;
}

.accordion__item--header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2rem 1rem 1rem 1rem;
  cursor: pointer;
}

.accordion__item.open {
  width: 100%;
}

.accordion__title {
  font-family: 'Lora';
  font-size: 2.4rem;
  line-height: 1.2;
  font-weight: 400;
  text-transform: uppercase;
}

.accordion__icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 2rem;
  height: 2rem;
  transition: transform .5s ease;
}

.accordion__icon span:first-child {
  transform: rotate(90deg) translateX(1px);
  width: 1.4rem;
  height: .1rem;
  background: currentColor;
}

.accordion__icon span {
  display: block;
  width: 1.4rem;
  height: .1rem;
  background: currentColor;
  cursor: pointer;
}

.accordion__icon.open {
  transform: rotate(45deg);
}

.accordion__content {
  font-family: 'Roboto', sans-serif;
  font-size: 1.6rem;
  line-height: 1.62;
  font-weight: 400;
  padding: 0 1rem 0 1rem;
  height: 0;
  transition: height .5s;
  overflow: hidden;
}

.accordion__content.open {
  margin-bottom: 1.2rem;
  height: 100%;
}
<div >
  <section >
    <div ></div>
    <div >
      <div >
        <div >
          <h5 >Visual direction</h5>
          <div >
            <span></span>
            <span></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Event production</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Brand creation</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
      <div >
        <div >
          <h5 >Design concept</h5>
          <div >
            <span ></span>
            <span ></span>
          </div>
        </div>
        <div  id="content__wrapper">
          <p >Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
          </p>
        </div>
      </div>
    </div>
</div>
</section>
</div>

  • Related