ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [모바일웹] 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 );

     

     

     

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

Designed by Tistory.