[css] 모바일 웹뷰 키보드 유무 확인 방법

해피데빙·2022년 12월 21일
0

출처 | https://sungchuni.tistory.com/20

모바일 브라우저의 키보드가 떴는지 확인하기

[배경] 모바일에서 사용하는 바텀 고정인 내비게이션 바가 온스크린 키보드가 있으면 내려가서 컨텐츠를 가리게 된다.

[목표] 앱이 아닌 모바일 웹뷰에서 input을 focus했을 때(즉, 화면에 키보드가 열려있는 경우에) bottom nav bar가 내려가도록 하기

[문제#1] 키보드 토글에 대한 자바스크립트 내장 이벤트가 없다

[문제#2]
ios, 안드로이드 모두 focus를 할 때는 문제 없지만,
안드로이드는 blur를 할 수 있는 방법이 두 가지다.

1)blur : input이 아닌 다른 곳 클릭
2)하단 backarrow 버튼을 통해 뒤로가기

2)처럼 뒤로가기를 하면 blur가 아니기 때문에 blur로 정의한 action이 일어나지 않는다
(끝내 해결 못한 예외 케이스)

[방법#1] vue에서 v-hide-bottom-nav라는 custom directive를 사용자가 직접 설정해 bottom nav bar를 숨길 수 있도록 한다

  1. nuxt에서 plugins/directives.js에서 각각 파일에서 정의한 directive들을 import해서 Vue에 등록한다
import directive이름 from 파일 위치;
import Vue from 'vue' 
export default function(){ 
 Vue.directive('directive이름', directive이름)
}
  1. custom directive를 정의할 때 쓸 수 있는 hook인 bind, unbind에 관련 내용을 정의한다
const handler = (vnode, hidden) => { // }
const bind = (el, binding, vnode){ // }
const unbind = (el, binding, vnode) => handler(vnode, false) 
export default { bind, unbind }
  • el : 요소
  • vnode는 virtual DOM을 구성하는 node로 context 등이 들어있다

[방법#2]

visualViewport API를 사용해서 뷰포트의 높이 차이로 키보드의 유무를 확인해 bottom nav bar를 숨기거나 보여준다

visualViewport.addEventListener('resize', handleResize); 
function handleResize(event){
  const {height: visualViewportHeight} = event.target;
  const eventName = Math.ceil(visualViewportHeight) < window.innerHeight ? "keyboardpen" : "keyboardclose"; 
  emitEvent.call(event, eventName) 
  
  function emitEvent(name){
    window.dispatchEvent(
      new CustomEvent(name, {
        detail : { 
          originalEvent: this
        }
      })
      //어떤 행동을 할지
    )
  }
}

visualViewport의 높이가 window의 내부 높이보다 작을 때 키보드가 열린 것이라 가정

  • 하지만 키보드 외에도 높이를 줄이는 요인들이 있을 수 있다
  • visualViewport의 높이는 double, window의 높이이기 때문에 올림 처리해서 사용
  • resize에넌 적당한 값의 debounce를 해서 불필요한 중복 트리거링을 방지한다
  • 터치 디바이스일 때만 작동하도록 pointer, hover 조건 추가
const {matches} = window.matchMedia("(hover:none), (pointer:coarse)"); 
if (matches && "VisualViewport" in window){//}

profile
노션 : https://garrulous-gander-3f2.notion.site/c488d337791c4c4cb6d93cb9fcc26f17

0개의 댓글