Mobile viewport height after orientation change

后端 未结 10 1401
孤街浪徒
孤街浪徒 2020-12-03 04:30

I am attaching a listener to the orientationchange event:

window.addEventListener(\'orientationchange\', function () {
    console.log(window.innerHeight);
}         


        
相关标签:
10条回答
  • 2020-12-03 04:53

    There is no way to capture the end of the orientation change event because handling of the orientation change varies from browser to browser. Drawing a balance between the most reliable and the fastest way to detect the end of orientation change requires racing interval and timeout.

    A listener is attached to the orientationchange. Invoking the listener starts an interval. The interval is tracking the state of window.innerWidth and window.innerHeight. The orientationchangeend event is fired when noChangeCountToEnd number of consequent iterations do not detect a value mutation or after noEndTimeout milliseconds, whichever happens first.

    var noChangeCountToEnd = 100,
        noEndTimeout = 1000;
    
    window
        .addEventListener('orientationchange', function () {
            var interval,
                timeout,
                end,
                lastInnerWidth,
                lastInnerHeight,
                noChangeCount;
    
            end = function () {
                clearInterval(interval);
                clearTimeout(timeout);
    
                interval = null;
                timeout = null;
    
                // "orientationchangeend"
            };
    
            interval = setInterval(function () {
                if (global.innerWidth === lastInnerWidth && global.innerHeight === lastInnerHeight) {
                    noChangeCount++;
    
                    if (noChangeCount === noChangeCountToEnd) {
                        // The interval resolved the issue first.
    
                        end();
                    }
                } else {
                    lastInnerWidth = global.innerWidth;
                    lastInnerHeight = global.innerHeight;
                    noChangeCount = 0;
                }
            });
            timeout = setTimeout(function () {
                // The timeout happened first.
    
                end();
            }, noEndTimeout);
        });
    

    I am maintaining an implementation of orientationchangeend that extends upon the above described logic.

    0 讨论(0)
  • 2020-12-03 04:55

    I solved this issue combining a couple of the above solutions. Resize would fire 4-5 times. Using .one, it fired too early. A short time out added to Christopher Bull's solution did the trick.

    $(window).on('orientationchange', function () {
      $(window).one('resize', function () {
        setTimeout(reference_to_function, 100);
      });
    });
    
    0 讨论(0)
  • 2020-12-03 04:56

    For people who just want the innerHeight of the window object after the orientationchange there is a simple solution. Use window.innerWidth. The innerWidth during the orientationchange event is the innerHeight after completion of the orientationchange:

    window.addEventListener('orientationchange', function () {
        var innerHeightAfterEvent = window.innerWidth;
        console.log(innerHeightAfterEvent);
        var innerWidthAfterEvent = window.innerHeight;
        console.log(innerWidthAfterEvent);
        console.log(screen.orientation.angle);
    });
    

    I am not sure if 180-degree changes are done in two 90 degree steps or not. Can't simulate that in the browser with the help of developer tools. But If you want to safeguard against a full 180, 270 or 360 rotation possibility it should be possible to use screen.orientation.angle to calculate the angle and use the correct height and width. The screen.orientation.angle during the event is the target angle of the orientationchange event.

    0 讨论(0)
  • 2020-12-03 04:58

    It is an experimental feature and gives the right innerHeight and innerWidth after screen orientation is changed.

    window.screen.orientation.addEventListener('change', function(){
        console.log(window.innerHeight)
    })
    

    I think listening to window resize is the safest way to implement screen orientation change logic.

    0 讨论(0)
  • 2020-12-03 05:00

    I also faced the same problem. So I ended up using:

    window.onresize = function(){ getHeight(); }
    
    0 讨论(0)
  • 2020-12-03 05:05

    Gajus' and burtelli's solutions are robust but the overhead is high. Here is a slim version that's reasonably fast in 2017, using requestAnimationFrame:

    // Wait until innerheight changes, for max 120 frames
    function orientationChanged() {
      const timeout = 120;
      return new window.Promise(function(resolve) {
        const go = (i, height0) => {
          window.innerHeight != height0 || i >= timeout ?
            resolve() :
            window.requestAnimationFrame(() => go(i + 1, height0));
        };
        go(0, window.innerHeight);
      });
    }
    

    Use it like this:

    window.addEventListener('orientationchange', function () {
        orientationChanged().then(function() {
          // Profit
        });
    });
    
    0 讨论(0)
提交回复
热议问题