[모바일웹] javascript mobile 가로모드, 세로모드 제어하기
현재 사용자 프로세스가 세로모드로만 가능하도록 하는 모바일웹을 만들고 있다. 라이브러리는 vue를 사용중이다.
* 최종 소스 (모든 브라우저, 기종에 전부 지원되는 버전)
timeout을 넣은 이유는 회전이 되기 전에 이벤트가 실행되어 가로모드, 세로모드를 반대로 읽어오는 경우가 있었음
window.addEventListener( "orientationchange", function() {
setTimeout( function() {
vueObj.currentOrientation();
}, 200 )
} )
function currentOrientation () {
this.$store.state.isVertical = ( window.innerHeight > window.innerWidth );
}
------------------------------------------------------------------------------
>> 여기서부터는 거쳐온 단계
1. orientationchange 이벤트 : 지원해주는 환경이 한정적임 ( ex - firefox )
// 회전 이벤트
window.addEventListener( "orientationchange", function( e ) {
vueObj.$store.state.isVertical = ( window.screen.orientation.angle === 0 );
} );
위의 소스는 회전이벤트가 먹힐 때마다 vue의 store 데이터를 변경해주는 소스이다.
orientationchange 이벤트를 이용해 화면회전에 따른 함수를 정의할 수 있다.
2. matchMediaList : 가로세로 모드를 css (가로와 세로 중 더 긴 길이를 기준으로 orientation을 판단)로 정의하기 때문에 모바일에서 자판영역이 나타났을 때 세로 영역이 줄어들면서 세로모드를 가로모드로 인식하는 경우가 있다.
let mql = window.matchMedia('(orientation:portrait)');
mql.addEventListener( "change", (e) => {
alert( "회전결과 : " + e.matches );
});
그래서 두 방법을 짬뽕시켜 작업 !
orientationchange이벤트는 firefox 에서 작동하지 않으므로 이벤트리스너는 matchMedia를 사용하고 내부로직에서 가로세로 구분점은 window.screen.orientation 을 사용했다.
let mql = window.matchMedia('(orientation:portrait)');
mql.addEventListener( "change", (e) => {
//angle이 0인 경우가 세로모드이다.
vueObj.$store.state.isVertical = ( window.screen.orientation.angle === 0 );
});
근데 이건 문제가 ios 에서 안되는 문제가 있었다..
window.screen 자체가 {} 빈 객체로 출력됨.
3. stackoverflow 에서는 해당 방법이 가장 정확할 것이라고 한다.
screen.availHeight와 screen.availWidth는 키보드 (mobile 자판) show, hide에 상관없이 모바일 웹 화면의 height와 width를 그대로 반환한다. 하지만 해당 방법은 처음에 가져온 모드(가로 또는 세로) 의 width, height를 계속 가져오기 때문에 변화할 때마다 동적으로 동작하지 않음
let currentOrientation = function() {
// Use screen.availHeight as screen height doesn't change when keyboard displays.
if(screen.availHeight > screen.availWidth){
// 세로모드일 때 실행할 이벤트
$("html").addClass('portrait').removeClass('landscape');
}
else {
// 가로모드일 때 실행할 이벤트
$("html").addClass('landscape').removeClass('portrait');
}
}
// Set orientation on initiliasation
currentOrientation();
// Reset orientation each time window is resized. Keyboard opening, or change in orientation triggers this.
window.addEventListener("resize", currentOrientation);
resize 이벤트는 지원환경이 많지 않으므로 resize 대신에 matchMedia change 이벤트를 사용하는 것도 좋은 방법이다 !
let mql = window.matchMedia('(orientation:portrait)');
mql.addEventListener( "change", this.currentOrientation );