STUDY/javascript

ios 키보드 올라왔을때 보고있던 화면 고정

수밤바 2022. 8. 23. 13:24
728x90

 

fixed로 화면 하단에 따라다니는 input창이 있는 UI

ios특성상 하단에 input이 있으면 focus 했을 때 키보드가 올라가면서 화면을 보고 있던 디바이스 너머로 밀어 올려 보낸다

이슈

 - 간헐적으로 키보드가 인풋 창을 덮어서 보이지 않는 현상

 - 내가 보고 있던 화면을 위로 올려버려서 시선을 잃는 현상

 

ios의 키보드를 올렸을때 화면 처리방식이 너무나 까다로워 검색하던중

'채널톡'이라는 서비스의 ios대응기 게시글을 참고했다. 

https://channel.io/ko/blog/cross_browsing_ios15

 

다만 내가 표현하고 싶은 부분과 다른점은

채널톡은 최신대화가 하단에 보여지기 때문에 최하단 화면으로 갱신해주면 되지만

나의경우 보고있던 화면을 이동시키지 않는것이 큰 차이점이였다.

 

아래  작업방식의 단점으로

스크롤이 막아놨기 때문에 글을쓰다가 위-아래로 스크롤이동을 할 수 없다는 단점이 있다.

 

 

 

 

 

 

// 글쓰기 모드
.keyboard--on {
  body {
    position: fixed;
  }
  .dim {
    opacity: 1;
    pointer-events: initial;
  }
}

키보드 호출 시 keyboard--on class 추가

스크롤되지 않게 body position:fixed 

dim show

 

 

 

input focus, focusout시 실행

focus시

현재 스크롤 값 저장과

html에 addClass keyboard--on

fixed 된 body의 top값을 현재 스크롤 값으로 세팅 

 

focusout시

html의 class remove

body의 top값 제거

윈도우 스크롤 active시 보고 있던 화면으로 돌려준다.

function active(){
   scroll = window.scrollY ;
   htmlEl.classList.add('keyboard--on');
   bodyEl.style.top=`${-scroll}px`;
}


 function reset(){
    htmlEl.classList.remove('keyboard--on');
    bodyEl.style.removeProperty('top');
    window.scrollTo(0,scroll)
 }

 

 

 

  let iosAsideGap = 0;
  let scroll;
  const bodyEl = document.body;
  const htmlEl = document.getElementsByTagName('html')[0];

  function handleVisualViewportResize() {  
    const currentVisualViewport = window.visualViewport.height;
    if (htmlEl.classList.contains('keyboard--on')) {
      const scrollHeight = window.document.documentElement.scrollHeight;
      iosAsideGap = scrollHeight - currentVisualViewport;
      window.scrollTo(0, iosAsideGap);
      bodyEl.style.top=`${-(scroll - iosAsideGap)}px`;
    }
  }
  window.visualViewport.onresize = handleVisualViewportResize;

window.visualViewport.height

window의 보이는 높잇값

평소에는 window.innerHeight와 동일한 값을 반환하여 어떤 차이인지 모르겠으나...

(아무튼) 정확한 차이는 모르겠으나 같은 값을 반환한다

 

키보드 올라왔을 때 html에 addClass를 해주었기 때문에

body에 position:fixed가 되어 높이값이 100%로 잡혀있다

visualViewport.height 출력해보면 내가 보고 있는 화면에서 키보드를 뺀 화면 높이값을 반환한다 (height:100% - 키보드 높이)

 

window.document.documentElement.scrollHeight

document의 높잇값

키보드가 올라왔을 경우 키보드 포함한 높이값을 반환한다(height:100%)

 

하여 window.document.documentElement.scrollHeight - window.visualViewport.height

키보드의 높이값과 사파리 모바일 브라우저의 하단 주소창과 같은 불필요한 요소의 높이값을 알 수 있다.

iosAsideGap = scrollHeight - currentVisualViewport;

 

스크롤 이동

스크롤을 최하단으로 이동시 하단의 불필요한 여백이 보인다(하단 주소창)

iosAsideGap만큼 스크롤을 이동시켜 보이는 최 하단에 딱 맞게 input field를 위치시킨다 

window.scrollTo(0, iosAsideGap);

 

 

마지막으로 fixed 된 body의 top값을 보고 있던 스크롤 위치 값과 iosAsideGap만큼 이동하여

화면 상단에 보일 수 있도록 위치시킨다

bodyEl.style.top=`${-(scroll - iosAsideGap)}px`;