오늘 모바일 H5 페이지 개발을 하다가 IOS에서 키보드를 수납하면 인터페이스가 원래 위치로 돌아가지 못하는 문제에 부딪혔습니다. 문제와 증상은 아래에 자세히 설명되어 있습니다.
페이지 구조문제의 페이지는 양식 구조입니다. 즉, 사용자가 메일링 정보를 입력할 수 있도록 div 아래에 4개의 입력 양식이 있는 구조와 유사합니다. 비슷한:
<div> <input type=text placeholder=성, 시,군을 입력해주세요/> <input type=text placeholder=주소를 입력해주세요/> <input type=text placeholder=이름을 입력해주세요/> < input type=text placeholder=주소/연락처/></div>를 입력해주세요
스크린샷은 다음과 같습니다.
키보드를 올리면 페이지가 자동으로 위로 이동합니다.사용자가 휴대폰에서 연락처를 입력하면 아이폰 키보드가 팝업됩니다. 이때 사용자가 전화 입력 상자를 볼 수 있도록 하기 위해 아이폰에서는 전체 페이지가 위로 이동됩니다(그렇지 않으면 키보드가 나타납니다). 전화 입력 상자를 덮을 것입니다). 이때 페이지 상단은 실제로 뷰포트에서 떨어진 거리의 일부입니다(인터페이스에서 입력 상자 행이 사라지는 것을 볼 수 있습니다).
키보드를 닫으면 페이지를 원래 위치로 복원할 수 없습니다.그러나 사용자가 입력을 완료하고 키보드를 닫으면 키보드를 치워도 페이지 위치가 복원되지 않습니다.
문제 분석실제로 이는 키보드를 접을 때 페이지의 일부가 뷰포트 밖으로 스크롤되는 것을 iOS가 방지할 수 없기 때문에 발생합니다. 이때 사용자는 손가락으로 페이지를 뒤로 끌 수 있습니다.
그러나 결국 경험은 좋지 않았습니다.
이 문제를 해결하기 위해 사용자 커서가 입력 상자를 떠날 때 window.scrollTo(0, 0)
호출하여 페이지를 스크롤하여 뷰포트 상단과 정렬함으로써 페이지 홈 효과를 얻을 수 있습니다.
이제 문제는 양식의 입력 상자 4개 모두에 흐림 이벤트를 추가한 다음 핸들러에서 window.scrollTo
호출하는 것입니다. 하지만 Vue의 @blur
통해 추가하든 DOM 작업을 통해 추가하든 4개의 이벤트 리스너를 추가해야 하는데 이는 그다지 우아하지 않습니다. 당연히 우리는 이벤트 프록시를 사용하는 것을 고려했습니다.
즉, 이벤트 리스너를 최상위 요소에 놓은 다음 트리거를 기다리는 inputBlur 함수를 정의합니다.
<div @blur=inputBlur> <input type=text placeholder=성, 시, 군을 입력해 주세요/> <input type=text placeholder=주소를 입력해 주세요/> <input type=text placeholder=입력해 주세요 name/> <input type=text placeholder=연락처 번호를 입력해주세요/></div>
그 결과 이벤트 리스너가 실행되지 않는 것으로 나타났습니다. 그 이유는 입력 상자의 blur
이벤트가 버블링될 수 없기 때문입니다.
쿼리 후에는 두 개의 DOM 이벤트인 focus
와 blur
사양에서 버블링될 수 없는 것으로 나타났습니다. 이와 유사하게 버블링할 수 있는 다른 두 가지 이벤트 focusin
및 focusout
가 있습니다.
인터넷의 일부 기사에서는 focusin
및 focusout
이 IE 브라우저에서만 지원되는 DOM 이벤트라고 언급했습니다. 실제로 MDN 문서를 보면 이 두 이벤트가 DOM 3 사양의 표준이 되었으며 수많은 브라우저에서 지원된다는 것을 알 수 있습니다.
따라서 이 두 가지 이벤트를 통해 문제를 결정적으로 해결하기 위해 focusout
변경하였습니다.
<div @focusout=inputBlur> <input type=text placeholder=성, 시, 군을 입력해 주세요/> <input type=text placeholder=주소를 입력해 주세요/> <input type=text placeholder=입력해 주세요 name/> <input type=text placeholder=연락처 번호를 입력해주세요/></div>
그런 다음 이벤트 핸들러를 구현합니다.
inputBlur(e) { // 먼저 이벤트를 트리거하는 대상 요소가 입력 상자인지 확인합니다. 입력 상자의 동작에만 중점을 둡니다. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { window.scrollTo(0,0) } },
이때 입력 상자에 내용을 입력한 후 키보드에서 마침을 클릭하여 키보드를 닫으면 예상한 효과가 나타납니다.
그러나 휴대폰에서 테스트한 결과 电话输入框
에서 姓名输入框
로 직접 전환하면 페이지가 흔들리는 것을 발견했습니다. 분석을 계속합시다.
사실 전환 시 두 개의 입력 상자가 흔들리는 이유도 매우 간단합니다. 위의 두 입력 상자 사이를 전환하면 페이지가 먼저 电话输入框
의 blur
이벤트를 트리거한 다음 姓名输入框
의 focus
이벤트를 트리거하기 때문입니다. 이 경우 흐림 현상이 발생하면 window.scrollTo(0,0)
가 트리거되어 페이지가 아래로 스크롤되고 姓名输入框
초점이 맞춰져 키보드가 계속 팝업됩니다. 페이지가 다시 위쪽으로 이동하게 됩니다.
실제로 두 입력 상자 사이를 전환할 때 첫 번째 입력 상자가 흐려지면 window.scrollTo
동작을 트리거할 필요가 없습니다. 그럼 입력 상자 전환 작업이 발생할 때 첫 번째 입력 상자의 동작이 끊어지도록 코드를 수정해 보겠습니다. 여기서는 setTimeout을 사용하여 해결합니다.
<div @focusout=inputBlur @focusin=inputFocus> <input type=text placeholder=도, 시, 군을 입력해 주세요/> <input type=text placeholder=주소를 입력해 주세요/> <input type=text placeholder= 이름을 입력해주세요/> < input type=text placeholder=연락처를 입력해주세요/></div>
inputBlur(e) { // 먼저 이벤트를 트리거하는 대상 요소가 입력 상자인지 확인합니다. 입력 상자의 동작에만 중점을 둡니다. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { // 입력 상자가 포커스를 잃고 IOS 키보드를 밖으로 밀어야 합니다. 페이지의 일부를 스크롤하여 복원합니다. 페이지를 창 상단으로 스크롤하고 정렬하세요. console.log('set time') this.timer = setTimeout(() => { console.log('timer Trigger') window.scrollTo(0,0); }, 0) } }, inputFocus(e) { // 포커스가 있는 경우 이전 입력 상자의 타이머를 제거합니다. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === '입력') {clearTimeout(this.timer) } }
위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.