-
[모바일웹] javascript mobile 가로모드, 세로모드 제어하기카테고리 없음 2021. 7. 13. 13:52
현재 사용자 프로세스가 세로모드로만 가능하도록 하는 모바일웹을 만들고 있다. 라이브러리는 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 );