skip to Main Content

i have this grid with 3 columns, and i wanted to make it so that when i click one of the divs it’ll go down a row and span the whole row, it also closes back up when i click on it again. and i got that to work. but i wanted to make it so that when i open a different div, itll close all the other ones if theyre open? so that theres only one open at a time? how would i do that?

<div id="gridALBUM">
  <div id="one"   onclick="toggles1()">  <h1>1</h1> <div><h2>one  </h2></div></div>
  <div id="two"   onclick="toggles2()">  <h1>2</h1> <div><h2>two  </h2></div></div> 
  <div id="three" onclick="toggles3()">  <h1>3</h1> <div><h2>three</h2></div></div>
  <div id="four"  onclick="toggles4()">  <h1>4</h1> <div><h2>four </h2></div></div>
  <div id="five"  onclick="toggles5()">  <h1>5</h1> <div><h2>five </h2></div></div>
  <div id="six"   onclick="toggles6()">  <h1>6</h1> <div><h2>six  </h2></div></div>
  <div id="seven" onclick="toggles7()">  <h1>7</h1> <div><h2>seven</h2></div></div>
  <div id="eight" onclick="toggles8()">  <h1>8</h1> <div><h2>eight</h2></div></div>
  <div id="nine"  onclick="toggles9()">  <h1>9</h1> <div><h2>nine </h2></div></div>
  <div id="ten"   onclick="toggles10()"> <h1>10</h1> <div><h2>ten </h2></div></div>
</div>

also, i have these other divs next to the h1 thatll have information in it, but i only want it to show if its parent div got expanded and spanned the whole row? so i want to change the display from hidden to block only IF it got opened.. i know i have to add or remove class hidesINFO but like, would i have to make a function for each div to do that?

#gridALBUM {
  margin: 50px auto;
  max-width: 908px;
  display: grid;
  grid-gap: 0 4px;
  grid-template-columns: repeat(3, 300px);
  background-color: lightblue;
}

#gridALBUM > div {
  border: 1px solid black;
  display: flex;
}

.hidesINFO {
  display: none;
}

.span {
  grid-column: 1 / 4;
  background-color: blue;
}

also, is there a better way to do the code below? instead of having to have the same exact code but with different IDs for each to target each div? because im gonna have to add more divs and i dont want to have to copy and paste each function when theyre really only doing the same thing, just to different elements

function toggles1() {
  document.getElementById("one").classList.toggle("span"); } 

function toggles2() {
  document.getElementById("two").classList.toggle("span"); } 

function toggles3() {
  document.getElementById("three").classList.toggle("span"); } 

function toggles4() {
  document.getElementById("four").classList.toggle("span"); } 

function toggles5() {
  document.getElementById("five").classList.toggle("span"); } 

function toggles6() {
  document.getElementById("six").classList.toggle("span"); } 

function toggles7() {
  document.getElementById("seven").classList.toggle("span"); } 

function toggles8() {
  document.getElementById("eight").classList.toggle("span"); } 

function toggles9() {
  document.getElementById("nine").classList.toggle("span"); } 

function toggles10() {
  document.getElementById("ten").classList.toggle("span"); } 

do i use siblings() to like, remove selectors? like would this work?

function toggles2() {
  document.getElementById("two").classList.toggle("span"); 
  document.getElementById("two").siblings().classList.remove("span");
  document.getElementById("two").siblings().child[1].classList.remove("hidesINFO");
}

2

Answers


  1. To access siblings you can go to your parentElement.children, but that is the least of issues with your code. It is too much repetitive. Have a look at this refactored version.

    function toggleSpan(item) {
      var state = item.classList.contains("span")
      Array.from(item.parentElement.children).forEach(function(child) {
        child.classList.remove("span");
      })
      item.classList.toggle("span", !state);
    }
    
    
    document.querySelectorAll(".number").forEach(function(item) {
      item.addEventListener('click', function(ev) {
    
        var number = item.getAttribute("data-number")
        console.log("number pressed", number)
    
        toggleSpan(item)
      })
    })
    #gridALBUM {
      margin: 50px auto;
      max-width: 908px;
      display: grid;
      grid-gap: 0 4px;
      grid-template-columns: repeat(3, 300px);
      background-color: lightblue;
    }
    
    #gridALBUM>div {
      border: 1px solid black;
      display: flex;
    }
    
    .hidesINFO {
      display: none;
    }
    
    .span {
      grid-column: 1 / 4;
      background-color: blue;
    }
    <div id="gridALBUM">
      <div id="one" data-number="1" class="number">
        <h1>1</h1>
        <div>
          <h2>one</h2>
        </div>
      </div>
      <div id="two" data-number="2" class="number">
        <h1>2</h1>
        <div>
          <h2>two</h2>
        </div>
      </div>
      <div id="three" data-number="3" class="number">
        <h1>3</h1>
        <div>
          <h2>three</h2>
        </div>
      </div>
      <div id="four" data-number="4" class="number">
        <h1>4</h1>
        <div>
          <h2>four</h2>
        </div>
      </div>
      <div id="five" data-number="5" class="number">
        <h1>5</h1>
        <div>
          <h2>five</h2>
        </div>
      </div>
      <div id="six" data-number="6" class="number">
        <h1>6</h1>
        <div>
          <h2>six</h2>
        </div>
      </div>
      <div id="seven" data-number="7" class="number">
        <h1>7</h1>
        <div>
          <h2>seven</h2>
        </div>
      </div>
      <div id="eight" data-number="8" class="number">
        <h1>8</h1>
        <div>
          <h2>eight</h2>
        </div>
      </div>
      <div id="nine" data-number="9" class="number">
        <h1>9</h1>
        <div>
          <h2>nine</h2>
        </div>
      </div>
      <div id="ten" data-number="10" class="number">
        <h1>10</h1>
        <div>
          <h2>ten</h2>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. JavaScript for jQuery .sibling() nodes is node.parentNode.childNodes[] see there

    But if I understood your question correctly…
    …You can simply use css :not() directive,
    with a .querySelectorAll() method.

    #gridALBUM > div:not(.span) > div {
      display : none; 
      }
    
    document.querySelectorAll('#gridALBUM > div').forEach((D,_,A)=>
      {
      D.addEventListener('click', e=>
        {
        if (D.classList.toggle('span'))
          A.forEach(d =>{ if(d!=D) d.classList.remove('span') });
        })
      })
    #gridALBUM {
      background : lightblue;
      margin     : 50px auto;
      max-width  : 908px;
      display    : grid;
      grid-gap   : 0 4px;
      grid-template-columns: repeat(3, 300px);
      }
    #gridALBUM > div {
      border  : 1px solid black;
      display : flex;
      }
    #gridALBUM > div:not(.span) > div {
      display : none; 
      }
    #gridALBUM > div.span {
      grid-column      : 1 / 4;
      background-color : #47479c;
      }
    <div id="gridALBUM">
      <div id="one"   ><h1>1</h1> <div><h2> one   </h2></div></div>
      <div id="two"   ><h1>2</h1> <div><h2> two   </h2></div></div> 
      <div id="three" ><h1>3</h1> <div><h2> three </h2></div></div>
      <div id="four"  ><h1>4</h1> <div><h2> four  </h2></div></div>
      <div id="five"  ><h1>5</h1> <div><h2> five  </h2></div></div>
      <div id="six"   ><h1>6</h1> <div><h2> six   </h2></div></div>
      <div id="seven" ><h1>7</h1> <div><h2> seven </h2></div></div>
      <div id="eight" ><h1>8</h1> <div><h2> eight </h2></div></div>
      <div id="nine"  ><h1>9</h1> <div><h2> nine  </h2></div></div>
      <div id="ten"   ><h1>10</h1><div><h2> ten   </h2></div></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search