当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《iPadWebApp:在Safari中使用JavaScript检测虚拟键盘?》经验,为你挑选了7个好方法。

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

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

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



1> LKM..:

我发现了一个有效的解决方案,虽然它有点难看.它也不适用于所有情况,但它适用于我.由于我正在调整用户界面的大小到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上测试过这个,看起来效果很好.


@fraxture:不知道一个全面的解释(如果你研究和写一个,我很乐意阅读它).这两个平台在主浏览器中处理屏幕键盘的方式截然不同.Android Chrome会缩小视口高度以为键盘腾出空间,因此在显示键盘时页面会调整大小.iOS Safari使用键盘覆盖页面(页面大小保持不变),并更改滚动的工作方式.Safari既可以在视口内滚动页面,也可以同时移动视口,确保在完全滚动时页面底部位于键盘上方.
@theSociableme:这个解决方案的重点是正确处理蓝牙键盘.如果你忽略了蓝牙键盘,弄清楚虚拟键盘是否显示会很容易,因为你可以检查一个字段是否有焦点.

2> Per Quested ..:

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

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

如果没有此代码段,应用容器将保持在向上滚动的位置,直到页面刷新.



3> 小智..:

或许更好的解决方案是在各种输入字段上绑定(在我的情况下使用jQuery)"blur"事件.

这是因为当键盘消失时,所有表单字段都会模糊.所以对于我的情况,这个剪辑解决了这个问题.

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

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

});

希望能帮助到你.米歇尔



4> ianh..:

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



5> Hafthor..:

在焦点事件期间,您可以滚动文档高度并神奇地滚动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,这是[previous] [next]工具栏的高度.

执行此检测时会有一点点闪烁,但似乎无法避免这种情况.


我刚刚在iOS 8.2中试过这个并且它不起作用...它是否在新iOS的某个阶段停止工作?

6> robocat..:

编辑:由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副作用.我没有使用其他建议的解决方案(更改scrolltop),因为在iOS上,当视口可缩放并滚动到聚焦输入时,滚动和缩放和焦点之间存在错误的交互(可以在视口外留下刚刚聚焦的输入 - 不是可见).



7> user1650613..:

仅在Android 4.1.1上测试过:

模糊事件不是测试键盘上下的可靠事件,因为用户可以选择明确隐藏键盘,而键盘不会触发导致键盘显示的字段上的模糊事件.

然而,如果键盘出于任何原因上升或下降,调整大小事件就像魅力一样.

咖啡:

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

任何时候出于任何原因显示或隐藏键盘时都会触发.

但是请注意,在Android浏览器(而不是应用程序)的情况下,有一个可伸缩的URL栏,它在缩回时不会调整大小,但会更改可用的窗口大小.

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有