✍️기록
📖 모바일 웹에서 position:fixed; bottom:0;
고정 시킨 영역이 키보드를 열었을 시 키보드 위에 자리 잡기.
※ 키보드 유무에 따른 대응
🔗 참고 url ⭐⭐⭐⭐⭐
✅ EX) 네이버앱 실행 네이버 검색 화면처럼 키보드 위에 영역
⚠️ 참고 : Safari -> 네이버 검색
🟢 Android - 삼성 인터넷, 네이버 앱 👈 원하는 동작.
🔴 Android - Chrome
🔴 IOS - Safari, Chrome
※ position: fixed 동작하지 않는 것이 아닌 가상의 영역 스크롤로 인해 동작하지 않는것처럼 보인다.
✅ IOS 테스트
✅ 문제의 키보드 열었을 시 가상영역
⌨️ 참고 url 채널톡 해결 방법
.wrap {
position:relative;
overflow-y: auto;
height:100%;
background:#FFF3CF;
}
#make-scrollable {
position: absolute;
left: 0;
width: 1px;
height: calc(100% + 1px);
/* 100% 보다 1px 높게 하여 .wrap scroll 발생하도록 */
}
⚠️ 채널톡 해결 방법과 차이가 있는 구조라서 그런지.. 문제 발견
✅ 다른 방법으로!!
✅ VisualViewport
👉 키보드가 생겼을 때 VisualViewport 사용해서
키보드 영역을 제외한 보여지는 view영역을 지정.
☝️
// 📍scroll
function handleWindowScroll(){
windowScroll.textContent = window.scrollY;
}
function handleViewportScroll(e){
viewportScroll.textContent = e.target.offsetTop;
}
// window scroll, visualViewport scroll 다르기에 둘 다 사용!
window.addEventListener('scroll',handleWindowScroll);
visualViewport.addEventListener("scroll", handleViewportScroll);
// 📍 resize
function viewportResize () {
const bodyHeight = document.body.offsetHeight;
const windowInnerHeight = window.innerHeight;
const viewportHeight = visualViewport.height;
// body height 확인용
bodyHeightText.textContent = bodyHeight;
// window height 확인용
windowHeightText.textContent = windowInnerHeight;
// viewport height 확인용
viewportHeightText.textContent = viewportHeight;
}
// visualVieport resize 사용
visualViewport.addEventListener('resize',viewportResize);
📍 👀 테스트 확인용
position: fixed 영역
✅ 테스트 확인 결과
✔️ 키보드를 열었을 때 viewport 값을 구해서 viewport 영역 활용.
✔️ window.scrollY, viewport scroll 차이 값을 활용.
✅ IOS 키보드 유무 확인
const windowInnerHeight = window.innerHeight;
const viewportHeight = parseInt(visualViewport.height);
let isKeyboard = false;
// ✔️ IOS 키보드 On & Off
if(windowInnerHeight > viewportHeight){
// 키보드 ON
isKeyboard = true;
}else{
// 키보드 OFF
isKeyboard = false;
}
✅ windowInnerHeight 보다 viewport height(보여지는 화면) 값이 작을 때 키보드를 열었을 경우로 생각!
// IOS 키패드 전체 화면 높이보다 viewport 높이가 작을 때
if(windowInnerHeight > viewportHeight){
isKeyboard = true;
// 👇 높이 지정
viewportwrap.style.height = `${viewportHeight}px`;
}else{
isKeyboard = false;
viewportwrap.style.height = "100%"; // or auto
}
✅ 키보드가 열린 후 스크롤 시 새롭게 높이가 지정된 viewport가 잘려 보이게 되는 문제를 해결하기 위해 2가지를 생각하였습니다.
1. 스크롤 시 키보드를 닫는다.
2. window scroll 값과 viewport scroll 값을 계산하여 viewport 영역을 움직인다.
✔️ 1번이 간단한 방법이지만 2번의 경우도 필요하여 테스트 진행!!
📍 👀 추가된 테스트 확인용
✅ 키보드 On - window.innerHeight > visualViewport.height
✅ viewport(가운데 위치한 녹색 영역)을 스크롤 시 보여지는 화면의 위치를 생각하고 스크롤 된 값과 비교!!
최종 값으로 transform:translateY으로 움직이게 하였습니다. 😁
// EX) 키보드 ON - scroll 이벤트
if(windowInnerHeight > viewportHeight){ // 키보드 ON
isKeyboard = true;
viewportwrap.style.height = `${viewportHeight}px`;
window.addEventListener('scroll',handleWindowScroll);
visualViewport.addEventListener("scroll", handleViewportScroll);
}else{ // 키보드 OFF - scroll 이벤트 해제
isKeyboard = false;
viewportwrap.style.height = "100%";
window.removeEventListener('scroll',handleWindowScroll);
visualViewport.removeEventListener("scroll", handleViewportScroll);
}
// scroll event
function handleWindowScroll(){
let viewportTopGap = parseInt(visualViewport.pageTop - visualViewport.offsetTop);
let translateY = parseInt(window.scrollY - viewportTopGap);
// 👇 scroll 변화에 따라 viewport div 이동
viewportwrap.style.transform = `translateY(${translateY}px)`;
}
// viewport scroll
function handleViewportScroll (e){
// viewport scroll
const viewportScrollY = parseInt(e.target.offsetTop);
// IOS에서는 사용하지 않고 확인용으로만 👀
// viewport scroll 값을 계산한다면 사용할 수 있습니다.
}
✅ viewport(녹색 영역) 스크롤 시 키보드 위로 움직임 확인
⚠️ 하단 가상영역으로 인해 스크롤 오차 발생.
문제의 하단 가상영역 | 스크롤 제한을 하여 가상영역이 보여지지 않도록 한다. |
---|
✅ scrollY(스크롤) + visualViewport.height (보여지는 화면 높이) > body height 넘는다면 더 이상 넘어가지 않도록
scroll 제한!!
// 가상 영역까지 스크롤 내려가는 것을 방지
if(window.scrollY + visualViewport.height > document.body.offsetHeight - 2){
window.scrollTo(0, document.body.offsetHeight - visualViewport.height-1);
}
✅ 자연스럽게 움직여지지 않고 있지만, viewport에 맞게 보여질 수 있도록 수정 완료!
⚠️ 더 자연스럽게, 중간 중간 끊김, 작은 오류, 추가로 수정이 필요!
✔️ Android 삼성 앱에서는 문제 없이 정상 동작 되지만 크롬 앱으로 확인 시
IOS와 동일하게 화면 일부가 키보드로 가려져 fixed가 정상 동작이 안되는 것처럼 확인.
🤔
가장 간단한 방법으로 IOS와 Android scroll 이벤트를 다르게 적용.
// Android 실행
function handleViewportScroll (e){
const viewportScrollY = parseInt(e.target.offsetTop);
viewportwrap.style.transform = `translateY(${viewportScrollY}px)`;
}
visualViewport.addEventListener("scroll", handleViewportScroll);
✔️ ☝️ viewport scroll에서만 동작을 했을 경우
IOS | Android Chrome |
---|
IOS의 경우 viewport scroll로만 움직임을 제어할 경우 window scroll이 멈춘 후에 동작 되듯이 보여 툭 툭 끊기는 움직임을 확인할 수 있습니다.
Android Chrome의 경우 viewport scroll로 움직임을 제어 시 부드러운 움직임을 확인할 수 있습니다.
✅ IOS와 Android 각 기능별로 나눠 사용.
✅ IOS에서 끊기지만 viewport scroll 하나로 둘 다 사용.
✅ IOS와 Android의 scroll 차이를 알고 있다면 굳이 나눠서 사용하지 않아도 충분히 사용이 가능!
⚠️ 좀 더 자연스럽고 오류 없는 움직임을 위해 추가로 수정이 필요.
✍️ 끝
감사합니다. 😁