-1

Trying to evade the problems that appears when you use vw and vh units in css (As the problem generated when using these units in mobile browsers), I started to use own vh and vw units, based on inner height and width as follows


function calcVH()
{

  return Math.floor((window.innerHeight * 0.01) * 10) / 10;
}

function calcVW()
{

  return Math.floor((window.innerWidth * 0.01) * 10) / 10;
}

function setVHAndVW() 
{

  document.documentElement.style.setProperty('--vh', `${calcVH()}px`);
  document.documentElement.style.setProperty('--vw', `${calcVW()}px`);
};

setVHAndVW();

window.addEventListener('resize', setVHAndVW);

This solves all the problems with vh and vw, but add another, to change the page orientation take a lot of time (incomprehensibly to me, traceback examples [Violation]'resize' handler took 399ms and [Violation]Forced reflow while executing JavaScript took 399ms) and ends with a bad results, making that the page its absolutely malformed (p.e. if you open the page in landscape and change to portrait, page looks like if you open the page in a desktop...).

Debugging de calc functions I found the problem, when I switch from landscape to portrait, window.innerXXX vars are misscalculate

EXAMPLE

Having an iPhone SE dimensions (375 x 667) and openning the page in landscape, the vars are wellcalculate (calcVH window.innerHeight 375 and calcVW window.innerWidth 667), then when I change the orientation the vars are calcVH window.innerHeight 1160 and calcVW window.innerWidth 653 which is incorrect (calcVH window.innerHeight 667 and calcVW window.innerWidth 375 expected)

Anyone knows the solution or one approach to it?


Applying the Ali Bahrami approach

The problem of changing between portrait and landscape is history, in the other direction problem is still occurring, but i did a new debbug with an interesting result.

Debug code

function calcVH()
{

  console.log('innerHeight', window.innerHeight)

  return Math.floor((window.innerHeight * 0.01) * 10) / 10;
}

function calcVW()
{

  console.log('innerWidth', window.innerWidth)

  return Math.floor((window.innerWidth * 0.01) * 10) / 10;
}

function setVHAndVW() 
{

  document.documentElement.style.setProperty('--vh', `${calcVH()}px`);
  document.documentElement.style.setProperty('--vw', `${calcVW()}px`);
};

setVHAndVW();

let resizeTimeout;

window.addEventListener('resize', () => 
{

  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(setVHAndVW, 100);
  resizeTimeout = setTimeout(setVHAndVW, 250);
  resizeTimeout = setTimeout(setVHAndVW, 1000);
});

Result of changing orientation from landscape to portrait

innerHeight 1160
innerWidth 653
innerHeight 1142
innerWidth 642
innerHeight 1125
innerWidth 632

The vars are decreasing with the time...


Trying a crazy debug, i found "the worst solution"

Crazy code

window.addEventListener('resize', () => 
{

  clearTimeout(resizeTimeout);

  for(let i = 0; i < 1000; ++i)
    resizeTimeout = setTimeout(setVHAndVW, i);
});

Result (only the firsts iterations)

innerHeight 1160
innerWidth 653
innerHeight 1142
innerWidth 642
innerHeight 1125
innerWidth 632
innerHeight 1107
innerWidth 622
innerHeight 1089
innerWidth 612
innerHeight 1071
innerWidth 602
innerHeight 1053
innerWidth 592
innerHeight 1036
innerWidth 582
innerHeight 1018
innerWidth 572
innerHeight 1000
innerWidth 562
innerHeight 982
innerWidth 552
innerHeight 965
innerWidth 542
innerHeight 947
innerWidth 532
innerHeight 929
innerWidth 522
innerHeight 911
innerWidth 512
innerHeight 893
innerWidth 502
innerHeight 876
innerWidth 492
innerHeight 858
innerWidth 483
innerHeight 840
innerWidth 472
innerHeight 822
innerWidth 462
innerHeight 804
innerWidth 452
innerHeight 787
innerWidth 443
innerHeight 769
innerWidth 432
innerHeight 751
innerWidth 422
innerHeight 733
innerWidth 412
innerHeight 716
innerWidth 402
innerHeight 698
innerWidth 392
innerHeight 680
innerWidth 382
innerHeight 667
innerWidth 375
innerHeight 667
innerWidth 375
innerHeight 667
innerWidth 375

As can be seen, the problem is not about time, because if I wait 1 second, the problem persist, but if i read the vars 1000 times (1 per ms) the problem dissapears in the 30 iteration (because the vars decrease until his valid value in each iteration)

Anyone could explain me how and how i could solve it?

  • What are the problems you speak of? What is the original issue you're trying to solve using this approach? – evolutionxbox Jul 11 '23 at 12:21
  • 1
    Does this answer your question? [Difference Between throttling and debouncing a function](https://stackoverflow.com/questions/25991367/difference-between-throttling-and-debouncing-a-function) – evolutionxbox Jul 11 '23 at 12:23

1 Answers1

0

Your issue seems to be caused by rapid firing of the 'resize' event before the browser finishes updating the viewport size. To solve it, use a timeout to delay the execution of the recalculation of the viewport dimensions. So something like:

let resizeTimeout;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(setVHAndVW, 300);
});

will do the job. Hope this helps.

Ali Bahrami
  • 910
  • 9
  • 21
  • Unfortunatelly, this only works when you switch from portrait to landscape, i tryied with 1 second of delay, and i got the same results switching from landscape to portrait – Daniel Álvarez Vega Jul 11 '23 at 12:38