我正在为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 '); }); });
通常情况下,您可能希望用户看不到这一点.不幸的是,至少在模拟器中运行时,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将文本字段滚动到视图中.可能有某种方法可以利用这种现象来检测键盘的存在(在页面底部有一个微小的文本字段,可以暂时获得焦点,或类似的东西).
在焦点事件期间,您可以滚动文档高度并神奇地滚动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]工具栏的高度.
执行此检测时会有一点点闪烁,但似乎无法避免这种情况.
编辑:由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上,当视口可缩放并滚动到聚焦输入时,滚动和缩放和焦点之间存在错误的交互(可以在视口外留下刚刚聚焦的输入 - 不是可见).
仅在Android 4.1.1上测试过:
模糊事件不是测试键盘上下的可靠事件,因为用户可以选择明确隐藏键盘,而键盘不会触发导致键盘显示的字段上的模糊事件.
然而,如果键盘出于任何原因上升或下降,调整大小事件就像魅力一样.
咖啡:
$(window).bind "resize", (event) -> alert "resize"
任何时候出于任何原因显示或隐藏键盘时都会触发.
但是请注意,在Android浏览器(而不是应用程序)的情况下,有一个可伸缩的URL栏,它在缩回时不会调整大小,但会更改可用的窗口大小.