¿Cómo hacer que el contenido aparezca en otro div cuando se hace clic en el título?

Resuelto 2205j00 asked hace 10 meses • 2 respuestas

Soy nuevo en JavaScript y estoy intentando crear una página donde los títulos de las entradas estarán a la izquierda (la barra lateral) y al hacer clic, el contenido aparecerá a la derecha (principal). el problema es que el contenido aparece directamente debajo del título, no al lado. Intenté cambiar el contenido al div en el que se supone que debe estar y cuando hago clic en el título no sucede nada. ¿Alguna idea sobre cómo solucionar este problema?

var entries = document.querySelectorAll(".entry");
for (var i = 0; i < entries.length; i++) {
  var el = entries[i];
  el.addEventListener("click", function () {
    var itemId = i;
    var allEntries = document.querySelectorAll(".entry");
    if (this.nextElementSibling.className.match("show")) {
      this.nextElementSibling.classList.remove("show");
    } else {
      this.nextElementSibling.classList.add("show");
    }
    for (var j = 0; j < allEntries.length; j++) {
      if (this == allEntries[j]) {
        continue;
      }
      allEntries[j].nextElementSibling.classList.remove("show");
    }
  });
}
.entry {
  color: #d49a95;
  cursor: pointer;
  padding: 10px;
}

.entry-content {
  display: none;
}

.show {
  display: block;
}
<div class="main">
  <div class="sidenav">
    <div class="entry">test</div>
    <div class="entry">test2</div>
  </div>
  <main>
    <center>
      <p class="entry-content">helloo</p>
      <p class="entry-content">hiiii</p>
    </center>
  </main>
</div>
Expandir fragmento

2205j00 avatar Feb 15 '24 23:02 2205j00
Aceptado

El problema se debe a que estás utilizando nextElementSibling()los .entryelementos en los que se hizo clic, pero no tienen hermanos. Según la descripción del problema, parece que estás intentando acceder a los .entry-contentelementos relacionados; sin embargo, son hijos de un hermano del padre del archivo .entry.

Para simplificar el problema, puedes relacionarlos por índice dentro de sus respectivos elementos principales, así:

const entries = document.querySelectorAll(".entry");
const contents = document.querySelectorAll('.entry-content');

const getChildIndex = el => [].indexOf.call(el.parentNode.children, el);
const hideAllContent = () => contents.forEach(c => c.classList.remove('show'));

entries.forEach(entry => {
  entry.addEventListener('click', e => {
    hideAllContent();
    
    const index = getChildIndex(e.target);
    contents[index].classList.add('show');
  });
});
.entry {
  color: #d49a95;
  cursor: pointer;
  padding: 10px;
}

.entry-content {
  display: none;
}

.show {
  display: block;
}
<div class="main">
  <div class="sidenav">
    <div class="entry">test</div>
    <div class="entry">test2</div>
  </div>
  <main>
    <center>
      <p class="entry-content">helloo</p>
      <p class="entry-content">hiiii</p>
    </center>
  </main>
</div>
Expandir fragmento

O, alternativamente, podría utilizar dataatributos en los .entryelementos para especificar directamente cuáles .entry-contentdeben mostrarse:

const entries = document.querySelectorAll(".entry");
const contents = document.querySelectorAll('.entry-content');
const hideAllContent = () => contents.forEach(c => c.classList.remove('show'));

entries.forEach(entry => {
  entry.addEventListener('click', e => {
    hideAllContent();
    document.querySelector(e.target.dataset.content).classList.add('show');
  });
});
.entry {
  color: #d49a95;
  cursor: pointer;
  padding: 10px;
}

.entry-content {
  display: none;
}

.show {
  display: block;
}
<div class="main">
  <div class="sidenav">
    <div class="entry" data-content="#content-a">test</div>
    <div class="entry" data-content="#content-b">test2</div>
  </div>
  <main>
    <center>
      <p class="entry-content" id="content-a">helloo</p>
      <p class="entry-content" id="content-b">hiiii</p>
    </center>
  </main>
</div>
Expandir fragmento

Además, aparte, usar cosas como cursor: pointerhacer que un elemento en el que no se puede hacer clic se comporte como un elemento en el que se puede hacer clic es una muy mala práctica. Le sugiero encarecidamente que cambie los .entryelementos a <a />, llamando preventDefault()si no desea que los enlaces vayan a ninguna parte.

Rory McCrossan avatar Feb 15 '2024 16:02 Rory McCrossan