programing

아이패드 웹 앱: 사파리에서 자바스크립트를 사용하여 가상 키보드를 감지합니까?

instargram 2023. 6. 1. 22:13
반응형

아이패드 웹 앱: 사파리에서 자바스크립트를 사용하여 가상 키보드를 감지합니까?

저는 아이패드용 웹 앱(일반 앱스토어 앱이 아니라 HTML, CSS, JavaScript를 사용하여 작성됨)을 작성하고 있습니다.키보드가 화면의 큰 부분을 차지하기 때문에 키보드가 표시될 때 남은 공간에 맞게 앱의 레이아웃을 변경하는 것이 합리적일 것입니다.그러나 키보드가 언제 표시되는지 또는 언제 표시되는지 감지할 수 있는 방법을 찾지 못했습니다.

제 첫 번째 아이디어는 텍스트 필드에 포커스가 있을 때 키보드가 보인다고 가정하는 것이었습니다.그러나 외부 키보드를 iPad에 연결하면 텍스트 필드가 포커스를 받을 때 가상 키보드가 표시되지 않습니다.

제 실험에서 키보드는 DOM 요소의 높이나 스크롤 높이에도 영향을 미치지 않았으며 키보드가 보이는지 여부를 나타내는 고유한 이벤트나 속성을 찾지 못했습니다.

조금 보기 흉하긴 하지만 효과가 있는 해결책을 찾았습니다.또한 모든 상황에서 효과가 있는 것은 아니지만, 저에게는 효과가 있습니다.사용자 인터페이스의 크기를 iPad의 창 크기에 맞게 조정하기 때문에 사용자는 일반적으로 스크롤할 수 없습니다.즉, 윈도우의 스크롤 Top을 설정하면 0으로 유지됩니다.

반면에 키보드가 표시되면 스크롤이 갑자기 작동합니다.따라서 ScrollTop을 설정하고 즉시 값을 테스트한 다음 재설정할 수 있습니다.jQuery를 사용하여 코드로 표시할 수 있는 방법은 다음과 같습니다.

$(document).ready(function(){
    $('input').bind('focus',function() {
        $(window).scrollTop(10);
        var keyboard_shown = $(window).scrollTop() > 0;
        $(window).scrollTop(0);

        $('#test').append(keyboard_shown?'keyboard ':'nokeyboard ');
    });
});

일반적으로 사용자가 볼 수 없을 것으로 예상됩니다.불행히도, 적어도 시뮬레이터에서 실행할 때 iPad는 눈에 띄게(빠르긴 하지만) 위 아래로 다시 스크롤됩니다.그래도, 적어도 특정 상황에서는 효과가 있습니다.

아이패드로 테스트해봤는데, 작동이 잘 되는 것 같습니다.

포커스 아웃 이벤트를 사용하여 키보드 해제를 탐지할 수 있습니다.흐리지만 거품이 납니다.키보드가 닫히면 작동합니다(물론 다른 경우도 있습니다).Safari 및 Chrome에서는 기존 메서드가 아닌 addEventListener에만 이벤트를 등록할 수 있습니다.여기 키보드 해제 후 폰갭 앱을 복구하는 데 사용한 예가 있습니다.

 document.addEventListener('focusout', function(e) {window.scrollTo(0, 0)});

이 스니펫이 없으면 앱 컨테이너는 페이지를 새로 고칠 때까지 위쪽으로 스크롤된 위치를 유지합니다.

화면에 키보드가 있는 경우 뷰포트 아래쪽에 있는 텍스트 필드에 초점을 맞추면 Safari가 텍스트 필드를 보기로 스크롤합니다.키보드의 존재를 감지하기 위해 이 현상을 이용할 수 있는 방법이 있을 수 있습니다(페이지 하단에 순간적으로 초점을 맞추는 작은 텍스트 필드 등).

아마도 약간 더 나은 해결책은 다양한 입력 필드에서 "흐림" 이벤트를 바인딩하는 것입니다(제 경우에는 jQuery).

키보드가 사라지면 모든 양식 필드가 흐려지기 때문입니다.그래서 저의 상황에서 이 캡처는 문제를 해결했습니다.

$('input, textarea').bind('blur', function(e) {

       // Keyboard disappeared
       window.scrollTo(0, 1);

});

도움이 되길 바랍니다.미켈레

편집: 실제로 작동하지는 못했지만 Apple에서 문서화: 키보드 디스플레이를 사용한 WKebView 동작: "iOS 10에서 WKebView 개체는 창을 업데이트하여 Safari의 기본 동작과 일치합니다. 키보드가 표시될 때 내부 높이 속성,크기 조정 이벤트를 호출하지 않음"(사용자는 크기 조정 대신 포커스 또는 포커스 + 지연을 사용하여 키보드를 탐지할 수 있습니다.)

편집: 코드는 외부 키보드가 아닌 화면 키보드를 사용합니다.정보가 화면 키보드에만 관심이 있는 다른 사람들에게 유용할 수 있기 때문에 그대로 두는 것입니다.http://jsbin.com/AbimiQup/4 사용하여 페이지 매개변수를 봅니다.

우리는 테스트를 통해 확인합니다.document.activeElement는 키보드(입력 유형=텍스트, 텍스트 영역 등)를 표시하는 요소입니다.

다음 코드는 일반적으로 정확하지는 않지만 우리의 목적을 위해 물건을 퍼지합니다.

function getViewport() {
    if (window.visualViewport && /Android/.test(navigator.userAgent)) {
        // https://developers.google.com/web/updates/2017/09/visual-viewport-api    Note on desktop Chrome the viewport subtracts scrollbar widths so is not same as window.innerWidth/innerHeight
        return {
            left: visualViewport.pageLeft,
            top: visualViewport.pageTop,
            width: visualViewport.width,
            height: visualViewport.height
        };
    }
    var viewport = {
            left: window.pageXOffset,   // http://www.quirksmode.org/mobile/tableViewport.html
            top: window.pageYOffset,
            width: window.innerWidth || documentElement.clientWidth,
            height: window.innerHeight || documentElement.clientHeight
    };
    if (/iPod|iPhone|iPad/.test(navigator.platform) && isInput(document.activeElement)) {       // iOS *lies* about viewport size when keyboard is visible. See http://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop: 
        return {
            left: viewport.left,
            top: viewport.top,
            width: viewport.width,
            height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45)  // Fudge factor to allow for keyboard on iPad
        };
    }
    return viewport;
}


function isInput(el) {
    var tagName = el && el.tagName && el.tagName.toLowerCase();
    return (tagName == 'input' && el.type != 'button' && el.type != 'radio' && el.type != 'checkbox') || (tagName == 'textarea');
};

위의 코드는 대략적인 것에 불과합니다.분할 키보드, 도킹 해제 키보드, 물리적 키보드에 대해 잘못된 것입니다., 은 사파리 이후)나이후)에서보다 더 을 할 수 입니다. 위의코멘트에따르면다당사에또신음것용있할여수을는은주작나이더코니하서입다을어진을드업은후보다이후(os▁asikw8위▁you▁be의▁at▁top▁on에,▁comment▁mayosios▁safari▁per▁wsince,os▁(당▁thansince멘▁the코신또▁code▁a▁givenview것)▁i르따▁do10kw주▁safari트에▁to면)▁i있할window.innerHeight소유물.

저는 다른 상황에서 오류를 발견했습니다. 예를 들어 입력에 초점을 맞춘 다음 홈 화면으로 이동하고 페이지로 돌아갑니다. iPad는 뷰포트를 작게 만들면 안 됩니다. 오래된 IE 브라우저는 작동하지 않습니다. Opera는 키보드를 닫은 후 요소에 초점을 맞추었기 때문에 작동하지 않았습니다.

그러나 뷰포트 확대/축소가 가능하거나 기본 설정에서 강제 확대/축소가 활성화된 경우 태그가 지정된 답변(스크롤 상단을 높이 측정으로 변경)에 심각한 UI 부작용이 발생합니다.iOS에서 뷰포트를 확대/축소할 수 있고 초점 입력으로 스크롤할 때 스크롤과 확대/초점 사이에 버그가 발생하기 때문에 다른 제안된 솔루션(스크롤 상단 변경)을 사용하지 않습니다.

포커스 이벤트가 진행되는 동안 문서 높이를 스크롤하여 마법처럼 window.inner 높이가 가상 키보드의 높이만큼 줄어듭니다.가상 키보드의 크기는 가로 방향과 세로 방향에 따라 다르므로 변경 시 다시 감지해야 합니다.사용자가 언제든지 블루투스 키보드를 연결/연결 해제할 수 있으므로 이러한 값을 기억하지 않는 것이 좋습니다.

var element = document.getElementById("element"); // the input field
var focused = false;

var virtualKeyboardHeight = function () {
    var sx = document.body.scrollLeft, sy = document.body.scrollTop;
    var naturalHeight = window.innerHeight;
    window.scrollTo(sx, document.body.scrollHeight);
    var keyboardHeight = naturalHeight - window.innerHeight;
    window.scrollTo(sx, sy);
    return keyboardHeight;
};

element.onfocus = function () {
    focused = true;
    setTimeout(function() { 
        element.value = "keyboardHeight = " + virtualKeyboardHeight() 
    }, 1); // to allow for orientation scrolling
};

window.onresize = function () {
    if (focused) {
        element.value = "keyboardHeight = " + virtualKeyboardHeight();
    }
};

element.onblur = function () {
    focused = false;
};

사용자가 Bluetooth 키보드를 사용할 때 키보드는높이는 [이전][다음] 도구 모음의 높이에 해당하는 44입니다.

이 탐지를 수행할 때 약간의 깜박임이 발생하지만, 이를 피할 수는 없을 것으로 보입니다.

비주얼 뷰포트 API는 가상 키보드 변경 및 뷰포트 가시성에 대응하기 위해 만들어졌습니다.

Visual Viewport API는 창의 Visual Viewport 속성을 쿼리하고 수정하기 위한 명시적 메커니즘을 제공합니다.시각적 뷰포트는 화면 키보드, 핀치 줌 영역 밖의 영역 또는 페이지 크기에 따라 확장되지 않는 다른 화면 아티팩트를 제외한 화면의 시각적 부분입니다.

function viewportHandler() {
  var viewport = event.target;
  console.log('viewport.height', viewport.height)
}

window.visualViewport.addEventListener('scroll', viewportHandler);
window.visualViewport.addEventListener('resize', viewportHandler);

Android 4.1.1에서만 테스트됨:

블러 이벤트는 키보드가 표시되도록 필드에서 블러 이벤트를 트리거하지 않는 키보드를 명시적으로 숨기기 위한 옵션으로 사용자가 키보드를 위아래로 테스트하는 신뢰할 수 있는 이벤트가 아닙니다.

크기 조정 이벤트는 어떤 이유로든 키보드가 위 또는 아래로 올 경우 매력적으로 작동합니다.

커피:

$(window).bind "resize", (event) ->  alert "resize"

어떤 이유로든 키보드가 표시되거나 숨겨질 때마다 실행됩니다.

그러나 안드로이드 브라우저(앱이 아닌)의 경우 접을 수 있는 URL 표시줄이 있어 접을 때 크기 조정이 실행되지 않지만 사용 가능한 창 크기가 변경됩니다.

키보드를 검색하는 대신 창의 크기를 검색합니다.

창 높이가 줄었는데 너비가 동일하면 키보드가 켜져 있음을 의미합니다.키보드가 꺼져 있으면 키보드에 추가하여 입력 필드가 포커스에 있는지 여부를 테스트할 수도 있습니다.

예를 들어 이 코드를 사용해 보십시오.

var last_h = $(window).height(); //  store the intial height.
var last_w = $(window).width(); //  store the intial width.
var keyboard_is_on = false;
$(window).resize(function () {
    if ($("input").is(":focus")) {
        keyboard_is_on =
               ((last_w == $(window).width()) && (last_h > $(window).height()));
    }   
});     

사용해 보십시오.

var lastfoucsin;

$('.txtclassname').click(function(e)
{
  lastfoucsin=$(this);

//the virtual keyboard appears automatically

//Do your stuff;

});


//to check ipad virtual keyboard appearance. 
//First check last focus class and close the virtual keyboard.In second click it closes the wrapper & lable

$(".wrapperclass").click(function(e)
{

if(lastfoucsin.hasClass('txtclassname'))
{

lastfoucsin=$(this);//to avoid error

return;

}

//Do your stuff 
$(this).css('display','none');
});`enter code here`

그 아이디어는 아래에 고정된 div를 추가하는 것입니다.가상 키보드가 표시되거나 숨겨진 스크롤 이벤트가 발생합니다.또한 키보드 높이도 확인할 수 있습니다.

const keyboardAnchor = document.createElement('div')
keyboardAnchor.style.position = 'fixed'
keyboardAnchor.style.bottom = 0
keyboardAnchor.style.height = '1px'
document.body.append(keyboardAnchor)
        
window.addEventListener('scroll', ev => {
  console.log('keyboard height', window.innerHeight - keyboardAnchor.getBoundingClientRect().bottom)
}, true)

        
        

이 솔루션은 스크롤 위치를 기억합니다.

    var currentscroll = 0;

    $('input').bind('focus',function() {
        currentscroll = $(window).scrollTop();
    });

    $('input').bind('blur',function() {
        if(currentscroll != $(window).scrollTop()){

        $(window).scrollTop(currentscroll);

        }
    });

문제는 2014년에도 소프트 키보드가 열려 있는 동안 장치가 화면 크기 조정 이벤트와 스크롤 이벤트를 일관성 없이 처리한다는 점입니다.

저는 여러분이 블루투스 키보드를 사용하더라도 iOS가 특히 이상한 레이아웃 버그를 유발한다는 것을 발견했습니다. 그래서 저는 소프트 키보드를 감지하는 대신에 매우 좁고 터치 스크린이 있는 장치를 목표로 삼아야 했습니다.

너비 감지에는 미디어 쿼리(또는 window.matchMedia)를 사용하고 터치 이벤트 감지에는 Modernizr을 사용합니다.

이전 답변에서 언급했듯이, window.innerHeight 변수는 이제 키보드가 나타나면 iOS10에서 제대로 업데이트되고 이전 버전에 대한 지원이 필요하지 않기 때문에 논의된 "솔루션"보다 조금 더 쉬울 수 있는 다음 해킹을 고안했습니다.

//keep track of the "expected" height
var windowExpectedSize = window.innerHeight;

//update expected height on orientation change
window.addEventListener('orientationchange', function(){
    //in case the virtual keyboard is open we close it first by removing focus from the input elements to get the proper "expected" size
    if (window.innerHeight != windowExpectedSize){
        $("input").blur();
        $("div[contentEditable]").blur();     //you might need to add more editables here or you can focus something else and blur it to be sure
        setTimeout(function(){
            windowExpectedSize = window.innerHeight;
        },100);
    }else{
        windowExpectedSize = window.innerHeight;
    }
});

//and update the "expected" height on screen resize - funny thing is that this is still not triggered on iOS when the keyboard appears
window.addEventListener('resize', function(){
    $("input").blur();  //as before you can add more blurs here or focus-blur something
    windowExpectedSize = window.innerHeight;
});

그러면 다음을 사용할 수 있습니다.

if (window.innerHeight != windowExpectedSize){ ... }

키보드가 보이는지 확인합니다.제 웹 앱에서 한동안 사용했는데 잘 작동하지만 (다른 모든 솔루션과 마찬가지로) "예상" 크기가 제대로 업데이트되지 않아서 실패하는 상황을 발견할 수도 있습니다.

앱 설정에서 사용자가 '외부 키보드 부착?'을 전환할 수 있는 확인란을 설정하는 것이 더 쉬울 수 있습니다.

작은 글씨로 현재 브라우저에서 외부 키보드를 인식할 수 없음을 사용자에게 설명합니다.

검색을 좀 해봤는데 "표시된 키보드에서" 또는 "해제된 키보드에서"에 대한 구체적인 내용을 찾을 수 없었습니다.지원되는 공식 이벤트 목록을 참조하십시오.또한 iPad용 기술 노트 TN2262를 참조하십시오.아마 이미 알고 계시겠지만, 신체적인 사건이 있습니다.onorientationchange연결하여 풍경/경관을 탐지할 수 있습니다.

비슷하게, 하지만 엉뚱한 추측은...크기 조정을 시도해 보셨습니까?뷰포트를 변경하면 표시/숨기기 중인 키보드에서 간접적으로 해당 이벤트가 트리거될 수 있습니다.

window.addEventListener('resize', function() { alert(window.innerHeight); });

그러면 크기 조정 이벤트에 대한 새 높이를 간단히 알 수 있습니다.

제가 직접 시도해본 적이 없어서, 그냥 생각일 뿐입니다.하지만 CSS로 미디어 쿼리를 사용하여 창의 높이가 언제 변경되는지 확인한 후 디자인을 변경해 본 적이 있습니까?저는 Safari 모바일이 키보드를 윈도우의 일부로 인식하지 않는다고 생각하기 때문에 작동하기를 바랍니다.

예:

@media all and (height: 200px){
    #content {height: 100px; overflow: hidden;}
}

입력 상자에 포커스가 있을 때 키보드의 높이를 알 수 있습니다.화면의 방향을 파악할 수 있는 CSS도 있으니 해킹해도 될 것 같습니다.

하지만 물리적 키보드의 경우 어떻게든 처리하고 싶을 것입니다.

언급URL : https://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari

반응형