iPad的Web应用程序:检测虚拟键盘在Safari中使用JavaScript?iPad的Web应用

2019-05-10 09:00发布

我正在写为iPad一个web应用程序( 而不是常规的App Store应用程序 -它使用HTML,CSS和JavaScript编写)。 由于键盘填补了屏幕的很大一部分,这将是有意义的改变应用程序的布局,以适应剩余空间显示在键盘的时候。 然而,我发现没有办法的时候或是否显示键盘检测。

我的第一个想法是假设键盘是可见的,当文本字段具有焦点。 然而,当外部键盘附接到一个iPad,虚拟键盘不显示在文本字段接收焦点。

在我的实验,键盘也没有影响任何DOM元素的高度或scrollHeight属性,我没有发现任何专有的事件或特性,这表明键盘是否可见。

Answer 1:

我发现了有效的解决方案,但它是一个有点难看。 它也不会在任何情况下工作,但它为我工作。 由于我调整用户界面到iPad的窗口尺寸的大小,用户通常无法滚动。 换句话说,如果我设置窗口的scrollTop的,它仍将维持在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的明显(虽然很快)滚动起来,再次回落。 尽管如此,它的工作原理,至少在某些特定的情况下。

我在iPad上进行了测试,它似乎很好地工作。



Answer 2:

您可以使用focusOut事件检测键盘解雇。 这就像模糊,但气泡。 当键盘关闭(但在其他情况下,当然),将火。 在Safari和Chrome的事件只能用的addEventListener登记,不与传统的方法。 下面是我用来恢复键盘解雇后的PhoneGap应用的例子。

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

如果没有这个片段中,应用程序容器留在向上滚动的位置,直到页面刷新。



Answer 3:

也许一个稍微好一点的解决方案是绑定(使用jQuery在我的情况)中的“模糊”事件上的各种输入字段。

这是因为当键盘消失所有表单域模糊。 因此,对于我的情况该文档片断解决了这个问题。

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

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

});

希望能帮助到你。 米歇尔



Answer 4:

如果有一个屏幕上的键盘,重点的文本字段,靠近视口的底部会导致Safari浏览器的文本字段滚动到视图。 可能有一些方法来利用此现象,检测键盘的存在(在页面的底部,它获得焦点瞬间,或类似的东西,有一个很小的文本字段)。



Answer 5:

在焦点事件可以滚动过去的原稿的高度和神奇的window.innerHeight由虚拟键盘的高度降低。 请注意,虚拟键盘的尺寸是横向和纵向模式不同,所以你需要发生变化时重新检测。 我建议不要记住这些值的用户可以进行连接/随时断开蓝牙键盘。

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;
};

注意,当用户正在使用蓝牙键盘,所述keyboardHeight是44其是[前] [下]的工具栏的高度。

还有就是当你做这个检测闪烁的点点,但它似乎并不可能,以避免它。



Answer 6:

编辑:由苹果记录在案虽然我不能真正得到它的工作:WKWebView 与键盘显示的行为 :“在iOS系统10,WKWebView通过显示键盘时更新他们的window.innerHeight属性的对象匹配Safari浏览器的原生行为,不叫调整事件”(也许可以使用对焦或对焦加上延迟来检测,而不是使用调整键盘)。

编辑:代码假定屏幕上的键盘,没有外接键盘。 离开它,因为信息可能是其他人只关心屏幕键盘非常有用。 使用http://jsbin.com/AbimiQup/4查看页面PARAMS。

我们测试以查看是否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');
};

上面的代码只是近似的:这是错误的分离式键盘,键盘脱开,物理键盘。 按在上面留言,您可以用做比Safari浏览器给定的代码更好的工作(因为iOS8上的?)或WKWebView(因为iOS10) window.innerHeight财产。

我发现故障在其他情况下:如给予重点投入再转到主屏幕,然后回到页; iPad的不应该让视小; 旧的IE浏览器将无法正常工作,歌剧没有工作,因为歌剧一直专注元素键盘关闭后。

然而,标签的答案(改变scrollTop的测量高度)有讨厌的UI副作用,如果视口缩放(或喜好启用强制变焦)。 我不使用其他建议的解决方案(改变scrollTop的),因为在iOS上,当视口缩放和滚动,以重点投入,有滚动和缩放和聚焦之间的相互作用越野车(也可以留下只是专注视的外部输入 - 不可见)。



Answer 7:

只测试了在Android 4.1.1:

模糊事件不是测试键盘上下可靠的事件,因为用户的明确隐瞒不触发导致键盘显示领域的模糊事件键盘的选项。

然而调整事件就像一个魅力如果键盘来向上或向下的任何理由。

咖啡:

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

近段时间火灾键盘显示或隐藏的任何理由。

但是请注意,对在Android浏览器(而不是应用程序)的情况下,有不火的时候,它被收回仍然不改变现有的窗口大小调整一个可伸缩的地址栏。



Answer 8:

代替检测键盘,尝试检测窗口的大小

如果该窗口的高度降低,并且宽度仍然是相同的,这意味着在键盘上。 否则键盘是关闭的,你也可以添加到,测试,如果任何输入字段上的焦点与否。

尝试例如该代码。

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()));
    }   
});     


Answer 9:

该解决方案还记得滚动位置

    var currentscroll = 0;

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

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

        $(window).scrollTop(currentscroll);

        }
    });


Answer 10:

试试这个:

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`


Answer 11:

正如在以前的答案某处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){ ... }

检查键盘是可见的。 我一直在使用了一段时间,现在在我的web应用程序,它工作得很好,但(所有其他解决方案),你可能会发现在那里,因为不更新“预期”大小正常或什么失败的情况。



Answer 12:

我做了一些搜索,我无法找到任何具体的“显示键盘上”或“键盘上的驳回”。 见支持的事件的正式名单 。 另请参阅技术说明TN2262为iPad。 正如你可能已经知道,有一种身体活动onorientationchange你就可以将最多检测横向/纵向。

同样的,但胡乱猜测......你尝试检测调整? 视改变可以从键盘间接触发事件被显示/隐藏。

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

这将只是提醒任意调整大小事件的新高度....



Answer 13:

我没有这个企图自己,所以它只是一个想法......但你尝试过使用媒体查询与CSS看到的窗口变化时的高度,然后更改了设计? 我可以想象移动Safari浏览器无法识别键盘作为窗口的一部分,这样将有希望的工作。

例:

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


Answer 14:

问题是,即使是在2014年,设备处理屏幕调整事件,以及滚动事件,而不一致的软键盘是开放的。

我发现,即使您使用的是蓝牙键盘,iOS设备尤其是触发一些奇怪的布局的bug; 所以不是检测软键盘,我刚刚来定位非常窄的设备,并有触摸屏。

我使用媒体查询(或window.matchMedia为宽度检测和) Modernizr的用于触摸事件检测。



Answer 15:

也许它更容易在你的应用程序的设置一个复选框,用户可以切换“连接外接键盘?”。

在小字,向用户说明外部键盘目前没有在今天的浏览器检测。



Answer 16:

上Safari浏览器,当一个元件被定位在屏幕和虚拟键盘的底部是可见的,由约1px的那个位置增加。 你可以利用这一点。

假设它是在横向模式下的移动设备

<div id="detector" style="position: absolute; bottom: 0"></div>

const detector = document.querySelector('#detector');
detector.getBoundingClientRect().bottom // 320

// when virtual keyboard is visible
detector.getBoundingClientRect().bottom // 329 or 328


Answer 17:

那么,你可以发现,当你输入框有焦点,你知道键盘的高度。 酒店还设有得到屏幕的方向CSS,所以我认为你可以破解它。

你想以某种方式处理物理键盘的情况下,虽然。



文章来源: iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari?