iPad Web App:在Safari中使用JavaScript检测虚拟键盘?

2020/11/12 14:22 · javascript ·  · 0评论

我正在为iPad编写一个Web应用程序(不是常规的App Store应用程序-它是使用HTML,CSS和JavaScript编写的)。由于键盘占据了屏幕的很大一部分,因此在显示键盘时更改应用程序的布局以适合剩余空间将是有意义的。但是,我发现没有办法检测何时或是否显示了键盘。

我的第一个想法是假设当文本字段具有焦点时键盘可见。但是,将外部键盘连接到iPad时,当文本字段获得焦点时,虚拟键盘不会显示。

在我的实验中,键盘也没有影响任何DOM元素的高度或滚动高度,而且我没有发现任何专有事件或属性来指示键盘是否可见。

我发现一个可行的解决方案,尽管它有点难看。它也不会在所有情况下都起作用,但是对我有用。由于我正在根据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 ');
    });
});

通常,您希望这对用户不可见。不幸的是,至少在Simulator中运行时,iPad可见(尽管很快)再次上下滚动。尽管如此,它至少在某些特定情况下仍然有效。

我已经在iPad上对此进行了测试,它似乎可以正常工作。

您可以使用focusout事件来检测键盘关闭就像模糊,但有气泡。键盘关闭时会触发(当然,在其他情况下也是如此)。在Safari和Chrome中,只能使用addEventListener来注册事件,而不能使用旧方法来注册。这是一个我在关闭键盘后恢复Phonegap应用程序的示例。

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

如果没有此代码段,则应用程序容器将保持向上滚动的位置,直到页面刷新为止。

也许更好的解决方案是在各个输入字段上绑定(以jQuery为例)“ blur”事件。

这是因为当键盘消失时,所有表单字段均会模糊。因此,就我的情况而言,此选项解决了问题。

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

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

});

希望能帮助到你。米歇尔

如果有屏幕键盘,则在视口底部附近聚焦文本字段将导致Safari将文本字段滚动到视图中。可能有某种方法可以利用这种现象来检测键盘的存在(页面底部有一个很小的文本字段,该文本字段会立即获得焦点,或类似的东西)。

在焦点事件期间,您可以滚动超过文档的高度,然后神奇地滚动窗口。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,它是[上一页] [下一页]工具栏的高度。

当您进行此检测时,会有一点闪烁,但似乎无法避免。

编辑:Apple记录,尽管我实际上无法使它工作:WKWebView带有键盘显示的行为:“在iOS 10中,WKWebView对象通过显示键盘时更新它们的window.innerHeight属性来匹配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');
};

上面的代码仅是近似值:拆分键盘,未对接键盘,物理键盘是错误的。根据顶部的注释,您可以使用window.innerHeight属性在Safari(自iOS8开始)或WKWebView(自iOS10开始)上比给定代码做得更好

我发现在其他情况下也会出现故障:例如,将注意力集中在输入上,然后转到主屏幕,然后返回页面;iPad不应缩小视口;旧的IE浏览器无法正常工作,Opera无法正常工作,因为在键盘关闭后Opera仍然专注于元素。

但是,如果视口可缩放(或在首选项中启用了强制缩放),则带标签的答案(将滚动顶部更改为度量高度)具有讨厌的UI副作用。我不使用其他建议的解决方案(更改滚动条),因为在iOS上,当视口可缩放并滚动到焦点输入时,滚动,缩放和焦点之间存在交互错误(这可能会将仅焦点输入留在视口之外-可见)。

仅在Android 4.1.1上测试:

blur事件不是向上和向下测试键盘的可靠事件,因为用户可以选择显式隐藏键盘,而不会在导致键盘显示的字段上触发模糊事件。

但是,如果键盘由于某种原因向上或向下移动,则resize事件可像超级按钮一样工作。

咖啡:

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

无论出于任何原因显示或隐藏键盘,均可在任何时候触发。

但是请注意,在Android浏览器(而非应用程序)的情况下,有一个可伸缩的网址栏,该网址栏在收起时不会触发调整大小,但会更改可用窗口的大小。

而不是检测键盘,请尝试检测窗口的大小

如果减小了窗口的高度,并且宽度仍然相同,则表示键盘已打开。否则,您可以在键盘关闭的情况下进行添加,测试是否有任何输入字段处于焦点上。

例如,尝试使用此代码。

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 currentscroll = 0;

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

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

        $(window).scrollTop(currentscroll);

        }
    });

试试这个:

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`

正如前面答案中提到的那样,当键盘出现时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应用程序中使用了一段时间,它运行良好,但是(与所有其他解决方案一样)您可能会发现由于“预期”大小未正确更新或其他原因而导致失败的情况。

我进行了一些搜索,但找不到“显示在键盘上”或“键盘关闭时”的具体内容。请参阅受支持事件的官方列表另请参阅适用于iPad的技术说明TN2262您可能已经知道,可以通过身体事件onorientationchange来检测风景/人像。

同样,但是有一个疯狂的猜测……您是否尝试过检测大小调整?视口的更改可能会通过显示/隐藏键盘间接触发该事件。

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

它将在任何调整大小事件时简单地警告新的高度。

我自己没有尝试过,所以这只是一个主意...但是您是否尝试过使用带有CSS的媒体查询来查看窗口的高度何时改变,然后针对该改变设计?我会想象Safari移动版不会将键盘识别为窗口的一部分,因此希望可以正常工作。

例:

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

问题是,即使在2014年,设备在打开软键盘时也不一致地处理屏幕调整大小事件和滚动事件。

我发现,即使您使用的是蓝牙键盘,iOS也会特别触发一些奇怪的布局错误。因此,除了检测软键盘之外,我只需要定位非常狭窄且具有触摸屏的设备。

我使用媒体查询(或window.matchMedia)进行宽度检测,并使用Modernizr进行触摸事件检测。

在您的应用程序设置中选中一个复选框,使用户可以切换“是否连接了外部键盘?”可能更容易。

用小字体向用户说明,当前在浏览器中无法检测到外部键盘。

这是我创建的一个小库,可用于制作Just Works(TM)的视口

https://github.com/adamjgrant/a-viewport-that-works

好了,您可以检测输入框何时具有焦点,并且知道键盘的高度。还有CSS可以用来获取屏幕方向,因此我认为您可以修改它。

但是,您可能希望以某种方式处理物理键盘的情况。

本文地址:http://javascript.askforanswer.com/ipad-web-appzaisafarizhongshiyongjavascriptjiancexunijianpan.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!