orientationchange
イベントにリスナーをアタッチしています:
window.addEventListener('orientationchange', function () {
console.log(window.innerHeight);
});
orientationchange
の後のドキュメントの高さを取得する必要があります。ただし、ローテーションが完了する前にイベントがトリガーされます。したがって、記録された高さは、実際の向きが変更される前の状態を反映しています。
方向の変更が完了した後で要素の寸法をキャプチャできるようにするイベントを登録するにはどうすればよいですか?
向きの変更には、新しい高さと幅を取得するための遅延が必要です。これは80%の確率で機能します。
window.setTimeout(function() {
//insert logic with height or width calulations here.
}, 200);
サイズ変更イベントを使用
resizeイベントには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
});
});
タイムアウトを使用しないでください
タイムアウトは信頼できません-一部のデバイスは、ハードコードされたタイムアウト内で向きの変更をキャプチャできません。これは、予期しない理由、またはデバイスが遅いことが原因である可能性があります。高速なデバイスでは、コードに不必要な遅延が逆に発生します。
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
});
});
向きの変更の処理はブラウザごとに異なるため、向きの変更イベントの終了をキャプチャする方法はありません。方向の変化の終わりを検出する最も信頼できる方法と最も速い方法のバランスをとるには、レース間隔とタイムアウトが必要です。
リスナーは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
の実装を維持しています。
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をすぐに取得します。これが誰かを助けることを願っています!
上記の解決策をいくつか組み合わせて、この問題を解決しました。サイズ変更は4〜5回発生します。 .oneを使用すると、起動が早すぎます。クリストファー・ブルのソリューションに追加された短時間のタイムアウトがうまくいった。
$(window).on('orientationchange', function () {
$(window).one('resize', function () {
setTimeout(reference_to_function, 100);
});
});
私も同じ問題に直面しました。だから私は結局使用しました:
window.onresize = function(){ getHeight(); }
これは実験的な機能であり、画面の向きが変更された後、適切なinnerHeightおよびinnerWidthを提供します。
window.screen.orientation.addEventListener('change', function(){
console.log(window.innerHeight)
})
ウィンドウのサイズ変更を聞くことが、画面の向きを変更するロジックを実装する最も安全な方法だと思います。
Orientationchangeは変更後の高さではなく、変更前の高さを取得することに注意してください。これを行うには、サイズ変更を使用します。
$(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);
});
});
innerHeight
の後にウィンドウオブジェクトのorientationchange
が必要なだけの場合は、簡単な解決策があります。 window.innerWidth
を使用します。 innerWidth
イベント中のorientationchange
は、innerHeight
の完了後のorientationchange
です。
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
イベントの目標角度です。