Home > other >  why "resize" event not working for my function to detect the height?
why "resize" event not working for my function to detect the height?

Time:01-26

I have a table with divs, and I want to each row get the biggest cell height. I have written a function to get it. On first load the function works properly, but when resizing the window, the function is not working. Can you tell me what's the problem?

const setHeight = function() {
  let hieghts = []
  let classes = 1
  let rowNum = document.querySelector("#desc").childElementCount
  for (classes; classes < rowNum; classes  ) {
    document.querySelectorAll(`.content${classes}`).forEach(td => {
      hieghts.push(td.clientHeight)
    })
    let max = Math.max(...hieghts)
    document.querySelectorAll(`.content${classes}`).forEach(td => {
      td.style.height = `${max}px`
    })
    max = 0
    hieghts = []
  }
}
window.addEventListener("resize", setHeight) // why this line not working?
setHeight();
.table {
  display: grid;
  grid-template-columns: repeat(6, auto);
  height: 90vh;
  border: 1px solid red;
}

.col {
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 1px solid;
}

.cells {
  display: block;
  width: 100%;
  border-bottom: 1px solid;
  padding: 5px;
  box-sizing: border-box;
}
<div >
  <div >
    <span >code title 1</span>
    <span >dev-1</span>
    <span >dev-2</span>
    <span >dev-3</span>
  </div>
  <div >
    <span >code </span>
    <span >1</span>
    <span >2</span>
    <span >3</span>
  </div>
  <div id="desc" >
    <span >description</span>
    <span >Lorem ipsum dolor sit  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
  </div>
  <div >
    <span >num</span>
    <span >1</span>
    <span >1</span>
    <span >1</span>
  </div>
  <div >
    <span >prise</span>
    <span >100</span>
    <span >200</span>
    <span >300</span>
  </div>
  <div >
    <span >total </span>
    <span >1000</span>
    <span >20000</span>
    <span >15000</span>
  </div>
</div>

CodePudding user response:

First off using a table would be much easier to control the height of the rows but Ill give you what you asked for. The main issue with your JavaScript is that you never clear the style on the rows so once the inital function runs they will always be the same. In order to achieve what you want you need to.

  1. Select all the cells
  2. Create a variable to store the biggest cell
  3. Loop over the cells and first clear their inline styles
  4. Run a conditional to see if the current cell is bigger than the biggest cell variable. If it is store that height as your new biggestCell value.
  5. Once all the cells are checked loop over the cells again and set the height to the biggestCell value.
  6. I also added a short debounce function (2 seconds) in order to keep your function from running every second the window is being resized.

function debounce(func, timeout = 200){
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => { func.apply(this, args); }, timeout);
  };
}

const checkHeight = function() {
  console.log("resize running...")
  const cells = document.querySelectorAll(".cells");
  let biggestCell = 0;
  for (let index = 0; index < cells.length; index  ) {
    const cell = cells[index];
    cell.style.height = "";
    if (cell.getBoundingClientRect().height > biggestCell) {
      biggestCell = cell.getBoundingClientRect().height;
    }
  }
  for (let index = 0; index < cells.length; index  ) {
    const cell = cells[index];
    cell.style.height = biggestCell   "px";
  }
}
window.addEventListener("resize", debounce(() => checkHeight()));
checkHeight();
.table {
  display: grid;
  grid-template-columns: repeat(6, auto);
  height: 90vh;
  border: 1px solid red;
}

.col {
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 1px solid;
}

.cells {
  display: block;
  width: 100%;
  border-bottom: 1px solid;
  padding: 5px;
  box-sizing: border-box;
}
<div >
  <div >
    <span >code title 1</span>
    <span >dev-1</span>
    <span >dev-2</span>
    <span >dev-3</span>
  </div>
  <div >
    <span >code </span>
    <span >1</span>
    <span >2</span>
    <span >3</span>
  </div>
  <div id="desc" >
    <span >description</span>
    <span >Lorem ipsum dolor sit  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
  </div>
  <div >
    <span >num</span>
    <span >1</span>
    <span >1</span>
    <span >1</span>
  </div>
  <div >
    <span >prise</span>
    <span >100</span>
    <span >200</span>
    <span >300</span>
  </div>
  <div >
    <span >total </span>
    <span >1000</span>
    <span >20000</span>
    <span >15000</span>
  </div>
</div>

CodePudding user response:

The problem is that you calculate the max value in a single for loop and try to set the row height in the table in the same loop. In this case, the row height retains its current state. You will see this logic error if you print the max value to the console in the old method; The height of all rows in the table is printed to the console, not the maximum value.

let rowNum = document.querySelector("#desc").childElementCount;

const setHeight = function() {
    let heights = [];

    /* All row heights are placed in the array. */
    for(let index = 1 ; index < rowNum ;   index)
    {
        document.querySelectorAll(`.content${index}`).forEach(td => {
            heights.push(td.clientHeight)
        });
    }
    
    /* Maximum row height is learned. */
    let max = Math.max(...heights);
    console.log(max);
    
    /* The maximum row height is assigned to all rows in the table. */    
    for(let index = 1 ; index < rowNum ;   index)
    {
        document.querySelectorAll(`.content${index}`).forEach(td => {
            td.style.height = `${max}px`
        });
    }
}

window.addEventListener("resize", setHeight);
setHeight();
.table {
  display: grid;
  grid-template-columns: repeat(6, auto);
  height: 90vh;
  border: 1px solid red;
}
.col {
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 1px solid;
}
.cells {
  display: block;
  width: 100%;
  border-bottom: 1px solid;
  padding: 5px;
  box-sizing: border-box;
}
<div >
  <div >
    <span >code title 1</span>
    <span >dev-1</span>
    <span >dev-2</span>
    <span >dev-3</span>
  </div>
  <div >
    <span >code </span>
    <span >1</span>
    <span >2</span>
    <span >3</span>
  </div>
  <div id="desc" >
    <span >description</span>
    <span >Lorem ipsum dolor sit  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
    <span >Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis incidunt inventore  </span>
  </div>
  <div >
    <span >num</span>
    <span >1</span>
    <span >1</span>
    <span >1</span>
  </div>
  <div >
    <span >prise</span>
    <span >100</span>
    <span >200</span>
    <span >300</span>
  </div>
  <div >
    <span >total </span>
    <span >1000</span>
    <span >20000</span>
    <span >15000</span>
  </div>
</div>

  •  Tags:  
  • Related