43

orientationchangeイベントにリスナーをアタッチしています:

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

の後にドキュメントの高さを取得する必要がありますorientationchange。ただし、ローテーションが完了する前にイベントがトリガーされます。したがって、記録された高さは、実際の向きが変わる前の状態を反映しています。

方向の変更が完了した後に要素の寸法をキャプチャできるようにするイベントを登録するにはどうすればよいですか?

4

10 に答える 10

32

サイズ変更イベントを使用する

サイズ変更イベントには、 orientationchange後の適切な幅と高さが含まれますが、すべてのサイズ変更イベントをリッスンする必要はありません。したがって、向きを変更した後、1回限りのサイズ変更イベントリスナーを追加します。

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);
});

jQuery

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

タイムアウトを使用しないでください

タイムアウトは信頼できません。一部のデバイスは、ハードコードされたタイムアウト内で方向の変更をキャプチャできません。これは、予期しない理由、またはデバイスの速度が遅いことが原因である可能性があります。高速デバイスでは、逆にコードに不要な遅延が発生します。

于 2018-03-20T11:40:59.390 に答える
21

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);
  });
}

次のように使用します。

window.addEventListener('orientationchange', function () {
    orientationChanged().then(function() {
      // Profit
    });
});
于 2017-06-16T02:11:09.077 に答える
16

向きの変更の処理はブラウザごとに異なるため、向きの変更イベントの終了をキャプチャする方法はありません。方向転換の終わりを検出するための最も信頼できる方法と最速の方法のバランスをとるには、レース間隔とタイムアウトが必要です。

リスナーがに接続されていorientationchangeます。リスナーを呼び出すと、インターバルが開始されます。window.innerWidth間隔はとの状態を追跡していwindow.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);
    });

私はorientationchangeend、上記のロジックを拡張した実装を維持しています。

于 2014-11-09T14:43:00.243 に答える
8

向きの変更は、新しい高さと幅を取得するために遅延が必要です。これは80%の時間で機能します。

window.setTimeout(function() {
    //insert logic with height or width calulations here.
}, 200);
于 2012-09-23T22:47:24.073 に答える
2

Gajus Kuizunasによって提案された回避策をしばらく使用しました。これは、少し遅いですが、信頼できるものでした。とにかく、ありがとう、それは仕事をしました!

CordovaまたはPhonegapを使用している場合、将来誰かがこの問題に直面した場合に備えて、より高速な解決策を見つけました。このプラグインは正しい幅/高さの値をすぐに返します:https ://github.com/pbakondy/cordova-plugin-screensize

ただし、返される高さと幅は実際の解像度を反映しているため、ビューポートピクセルを取得するにはwindow.devicePixelRatioを使用する必要がある場合があります。また、タイトルバー(バッテリー、時間など)は返される高さに含まれます。このコールバック関数を最初に使用しました(onDeviceReady)

var successCallback = function(result){
    var ratio = window.devicePixelRatio;            
    settings.titleBar = result.height/ratio-window.innerHeight; 
    console.log("NEW TITLE BAR HEIGHT: " + settings.titleBar);
};

向き変更イベントハンドラーでは、次を使用できます。

height = result.height/ratio - settings.titleBar;

すぐにinnerHeightを取得します。これが誰かに役立つことを願っています!

于 2016-01-06T12:26:48.417 に答える
2

上記のいくつかの解決策を組み合わせて、この問題を解決しました。サイズ変更は4-5回発砲します。.oneを使用すると、発火が早すぎました。Christopher Bullのソリューションに追加された短いタイムアウトで、うまくいきました。

$(window).on('orientationchange', function () {
  $(window).one('resize', function () {
    setTimeout(reference_to_function, 100);
  });
});
于 2019-10-01T23:54:25.680 に答える
1

私も同じ問題に直面しました。だから私は使用することになりました:

window.onresize = function(){ getHeight(); }
于 2014-05-26T06:38:18.373 に答える
1

これは実験的な機能であり、画面の向きを変更した後、正しいinnerHeightとinnerWidthを提供します。

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

ウィンドウのサイズ変更を聞くことが、画面の向きを変更するロジックを実装する最も安全な方法だと思います。

于 2019-03-06T20:46:05.757 に答える
1

方向の変更は、変更後ではなく、変更前の高さを取得することに注意することが重要です。これを行うには、サイズ変更を使用します。

$(window).bind('orientationchange', function (e) {
    var windowHeight = $(window).innerHeight();
    console.log('Before Orientation: Height = ' + windowHeight);

    $(window).resize(function () {
        windowHeight = $(window).innerHeight();
        console.log('After Orientation: Height = ' + windowHeight);
    });
});
于 2019-04-06T13:31:38.527 に答える
-1

innerHeight後にウィンドウオブジェクトのを必要とする人のためorientationchangeに、簡単な解決策があります。を使用しwindow.innerWidthます。イベントinnerWidth中は:の完了後です。orientationchangeinnerHeightorientationchange

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

180度の変更が2つの90度のステップで行われるかどうかはわかりません。開発者ツールの助けを借りてブラウザでそれをシミュレートすることはできません。ただし、180、270、または360回転の可能性を完全に防ぐにはscreen.orientation.angle、角度の計算と正しい高さと幅の使用が可能である必要があります。イベント中は、イベントのscreen.orientation.angleターゲット角度ですorientationchange

于 2018-07-22T10:10:31.943 に答える