카테고리 없음

[모바일웹] javascript mobile 가로모드, 세로모드 제어하기

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

 

 

 

참고 : https://stackoverflow.com/questions/8883163/css-media-query-soft-keyboard-breaks-css-orientation-rules-alternative-solut