方向改变后的移动视口高度

Dan*_*nze 30 javascript mobile html5 viewport orientation-changes

我正在为这个orientationchange事件添加一个监听器:

window.addEventListener('orientationchange', function () {
    console.log(window.innerHeight);
});
Run Code Online (Sandbox Code Playgroud)

我需要获得文件的高度orientationchange.但是,事件在旋转完成之前触发.因此,记录的高度反映了实际方向变化之前的状态.

如何在完成方向更改后注册允许我捕获元素尺寸的事件?

Chr*_*ull 22

使用resize事件

调整大小事件将包括一个经过适当的宽度和高度orientationchange,但你不想监听所有的调整大小事件.因此,我们在方向更改后添加一次性调整大小事件侦听器:

Javascript:

window.addEventListener('orientationchange', function() {
    // After orientationchange, add a one-time resize event
    var afterOrientationChange = function() {
        // YOUR POST-ORIENTATION CODE HERE
        // Remove the resize event listener after it has executed
        window.removeEventListener('resize', afterOrientationChange);
    };
    window.addEventListener('resize', afterOrientationChange);
});
Run Code Online (Sandbox Code Playgroud)

jQuery:

$(window).on('orientationchange', function() {
    // After orientationchange, add a one-time resize event
    $(window).one('resize', function() {
        // YOUR POST-ORIENTATION CODE HERE
    });
});
Run Code Online (Sandbox Code Playgroud)

不要使用超时

超时不可靠 - 某些设备无法在您的硬编码超时内捕获其方向变化; 这可能是出于不可预见的原因,或者因为设备很慢.快速设备将在代码中反向产生不必要的延迟.

  • 到目前为止,这是最好的答案。 (2认同)
  • 大家好,我发现这种方法有一些致命的问题。如果你在chrome移动模式下使用它,如果你在触发$(window).one('resize')后立即尝试获取window.innerHeight,你无法获得正确的值,它会给你(rightValue * ZoomRate) )。另一个问题是,当我在 ipad 中使用它时,我总是得到错误的值,但是,我不知道原因。 (2认同)
  • 同样在这里。在 iPhone Safari 上无法正常工作。除非我在 500 毫秒后添加 get insideHeight,否则它会得到不正确的高度 (2认同)

kiz*_*zx2 15

Gajus'和burtelli的解决方案非常强大,但开销很高.这是一款在2017年相当快的超薄版本,使用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);
  });
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

window.addEventListener('orientationchange', function () {
    orientationChanged().then(function() {
      // Profit
    });
});
Run Code Online (Sandbox Code Playgroud)


Gaj*_*jus 14

无法捕获方向更改事件的结束,因为方向更改的处理因浏览器而异.在最可靠和最快速的检测方向变化结束方式之间取得平衡需要比赛间隔和超时.

听众附在orientationchange.调用侦听器会启动一个间隔.的间隔被跟踪的状态window.innerWidthwindow.innerHeight.在orientationchangeend当事件被触发noChangeCountToEnd后续的迭代次数不检测值突变或之后noEndTimeout毫秒,先发生者为准.

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);
    });
Run Code Online (Sandbox Code Playgroud)

我正在维持一个实现orientationchangeend,扩展到上述逻辑.


Dan*_*nze 9

方向变化需要延迟以获得新的高度和宽度.这有80%的时间都有效.

window.setTimeout(function() {
    //insert logic with height or width calulations here.
}, 200);
Run Code Online (Sandbox Code Playgroud)