javascript - attribute - Altura de la ventana móvil después del cambio de orientación
title css (7)
Estoy adjuntando un oyente al evento de cambio de orientationchange
:
window.addEventListener(''orientationchange'', function () {
console.log(window.innerHeight);
});
Necesito obtener la altura del documento después del cambio de orientationchange
. Sin embargo, el evento se activa antes de que se complete la rotación. Por lo tanto, la altura registrada refleja el estado antes del cambio de orientación real.
¿Cómo registro un evento que me permita capturar las dimensiones del elemento después de que se haya completado el cambio de orientación?
El cambio de orientación necesita un retraso para recoger las nuevas alturas y anchuras. Esto funciona el 80% del tiempo.
window.setTimeout(function() {
//insert logic with height or width calulations here.
}, 200);
Las soluciones de Gajus y Burtelli son robustas pero la sobrecarga es alta. Aquí hay una versión delgada que es razonablemente rápida en 2017, utilizando 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);
});
}
Úsalo así:
window.addEventListener(''orientationchange'', function () {
orientationChanged().then(function() {
// Profit
});
});
No hay manera de capturar el final del evento de cambio de orientación porque el manejo del cambio de orientación varía de un navegador a otro. Hacer un balance entre la forma más confiable y la más rápida para detectar el final del cambio de orientación requiere un intervalo de carrera y un tiempo de espera.
Un oyente se adjunta a la orientationchange
. Al invocar al oyente se inicia un intervalo. El intervalo es el seguimiento del estado de window.innerWidth
y window.innerHeight
. El evento de cambio de orientationchangeend
se noChangeCountToEnd
cuando el número de iteraciones noChangeCountToEnd
no detecta una mutación de valor o después de milisegundos noEndTimeout
, lo que ocurra primero.
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);
});
Mantengo una implementación de cambio de orientationchangeend
que se extiende sobre la lógica descrita anteriormente.
Para las personas que solo desean la innerHeight
del objeto de la ventana después de la orientationchange
hay una solución simple. Utilice window.innerWidth
. El valor de innerWidth
durante el cambio de orientationchange
es la innerHeight
después de completar el cambio de orientationchange
:
window.addEventListener(''orientationchange'', function () {
var innerHeightAfterEvent = window.innerWidth;
console.log(innerHeightAfterEvent);
var innerWidthAfterEvent = window.innerHeight;
console.log(innerWidthAfterEvent);
console.log(screen.orientation.angle);
});
No estoy seguro de si los cambios de 180 grados se realizan en dos pasos de 90 grados o no. No se puede simular eso en el navegador con la ayuda de herramientas de desarrollo. Pero si desea protegerse contra una posibilidad de rotación completa de 180, 270 o 360, debería ser posible usar screen.orientation.angle
para calcular el ángulo y usar la altura y el ancho correctos. El screen.orientation.angle
durante el evento es el ángulo objetivo del evento de cambio de orientationchange
.
También me enfrenté al mismo problema. Así que terminé usando:
window.onresize = function(){ getHeight(); }
Utilicé la solución propuesta por Gajus Kuizunas por un tiempo que era confiable aunque un poco lenta. Gracias, de todos modos, hizo el trabajo!
Si está utilizando Cordova o Phonegap, encontré una solución más rápida, en caso de que alguien más se enfrente a este problema en el futuro. Este complemento devuelve los valores correctos de ancho / alto de inmediato: https://github.com/pbakondy/cordova-plugin-screensize
Sin embargo, la altura y el ancho devueltos reflejan la resolución real, por lo que es posible que tenga que usar window.devicePixelRatio para obtener los píxeles de la ventana gráfica. También la barra de título (batería, tiempo, etc.) se incluye en la altura devuelta. Utilicé esta función de devolución de llamada inicialmente (onDeviceReady)
var successCallback = function(result){
var ratio = window.devicePixelRatio;
settings.titleBar = result.height/ratio-window.innerHeight;
console.log("NEW TITLE BAR HEIGHT: " + settings.titleBar);
};
En el controlador de eventos de cambio de orientación, puede utilizar:
height = result.height/ratio - settings.titleBar;
para obtener la altura interior de inmediato. ¡Espero que esto ayude a alguien!
Usa el evento resize
El evento de cambio de tamaño incluirá el ancho y la altura apropiados después de un cambio de orientación , pero no desea escuchar todos los eventos de cambio de tamaño. Por lo tanto, agregamos un detector de eventos de cambio de tamaño único después de un cambio de orientación:
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
});
});
NO use tiempos de espera
Los tiempos de espera no son confiables: algunos dispositivos no podrán capturar su cambio de orientación dentro de sus tiempos de espera codificados; Esto puede ser por razones imprevistas, o porque el dispositivo es lento. Los dispositivos rápidos tendrán inversamente un retraso innecesario en el código.