如何通过Javascript/Sencha监听键盘开启和关闭?

21

我有一个使用HTML5/Javascript(Sencha)构建的应用程序,我已经将其打包到XCode中的PhoneGap中以在iOS上运行。无论如何,我希望能够监听键盘的打开/关闭事件并相应地进行一些操作。是否有任何方法可以实现这一点?


当您集中于文本字段、文本区域字段等时,键盘将自动调用。因此,您可以在JavaScript中创建聚焦事件的监听器。 - heyjii
那么,我还想监听文本字段等失去焦点的事件,有这样的事件吗? - Groppe
我认为你可以使用模糊事件。 - heyjii
它起作用了。如果你想继续发布一个实际的答案,我会给你打勾。 - Groppe
很高兴听到这个消息...我会将其发布为答案。 - heyjii
7个回答

23

当您聚焦于文本输入框、文本域时,键盘会自动弹出。因此,您可以在JavaScript中创建监听器以侦听 focus 事件,这类似于侦听键盘打开事件。同样,您也可以使用 blur 监听器来处理键盘关闭。

谢谢。


我正在使用这个代码来设置焦点。inpMessage.fieldEl.dom.focus(); 在谷歌浏览器中它可以正常工作,但在设备上无法正常工作。 - amrit_neo
2
请注意,此代码将在键盘动画打开之前触发,因此如果您需要进行定位/布局调整,则可能太早。 - Andrew Bullock
24
发布答案前,您需要进行更多的测试。当您在Android设备上点击返回按钮时,键盘会隐藏,但不会触发模糊事件。 - Nick Song
@devmaniac...感谢您的反馈。我并不是说隐藏键盘会调用模糊事件。如果我们调用一个当前聚焦的文本字段的模糊事件,它将隐藏键盘。这只是相反的情况。 :) - heyjii

14

最近我也遇到了一个类似的问题。经过一些研究,我发现“视觉视口API”是解决方法。

“视觉视口是屏幕上可见的部分,不包括屏幕键盘、缩放区域外的区域或任何不随页面尺寸变化而缩放的其他屏幕工件。”

https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

window.visualViewport.addEventListener('resize', event => console.log(event.target));

每当“可视窗口”调整大小时,例如键盘打开/关闭时,以上代码将被执行。


我认为这是最好的答案,因为它允许您避免将此功能紧密耦合到本地层集成中。因此,如果该应用程序从PhoneGap移动到仅Web、React Native或本机Web视图,则无需更改实现。 - Tina

12

1
这个能在浏览器上运行吗?因为那个库似乎是为 Cordova 设计的。 - Ricardo G. Fretes
2
你确实需要使用 Phonegap/Cordova(注意,这个回答已经有7年了)。 - Nicolas

4
触发打开状态很容易使用onclick或onfocus事件,但是在关闭键盘时,onblur事件不会被触发(因为光标仍然停留在输入/文本区域中)。因此,我通过检测窗口高度来找到解决方案,在键盘打开/关闭时窗口高度会显着改变。这个方法在Android和iOS的现代浏览器中也可以工作。演示:http://jsfiddle.net/qu1ssabq/3/ 如果需要,您可以改进我的代码以适用于不支持addEventListener或innerHeight的设备 - 在互联网上有可用的替代品。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, minimal-ui">
<title>Detect keyboard opened/closed event</title>
</head>
<body>

<textarea id="txta" onclick="xfocus()" onblur="xblur()"></textarea><br>

<span id="status" style="background: yellow; width: auto;">closed</span>

<script type="text/javascript">
  function xfocus() {
    setTimeout(function() {
      height_old = window.innerHeight;
      window.addEventListener('resize', xresize);
      document.getElementById('status').innerHTML = 'opened'; // do something instead this
    }, 500);
  }
  function xresize() {
    height_new = window.innerHeight;
    var diff = Math.abs(height_old - height_new);
    var perc = Math.round((diff / height_old) * 100);
    if (perc > 50)
      xblur();
  }
  function xblur() {
    window.removeEventListener('resize', xresize);
    document.getElementById('status').innerHTML = 'closed'; // do something instead this
  }
</script>

</body>
</html>

3
根据camiloHimura的答案所建议的,您可以利用window.visualViewport

视口是屏幕的可视部分,不包括屏幕键盘、缩放区域外的区域或任何不随页面尺寸变化而缩放的其他屏幕工件。

我在几个设备上打开键盘时测量了window.screen.heightwindow.visualViewport.height之间的差异,它总是大于300px
因此,您可以像这样做:
const listener = () => {
  const MIN_KEYBOARD_HEIGHT = 300 // N.B.! this might not always be correct
    
  const isMobile = window.innerWidth < 768
  const isKeyboardOpen = isMobile 
    && window.screen.height - MIN_KEYBOARD_HEIGHT > window.visualViewport.height
}

window.visualViewport.addEventListener('resize', listener)


你应该记住,这个解决方案可能在所有情况下都不适用,因为它严重依赖于假设所有设备的键盘高度大致相同。当然,你可以调整硬编码的值,但是正如你所看到的,这并不是一个万无一失的解决方案。

2

另一个可能的(但非常hacky的)解决方案是监听窗口调整大小事件。它不适用于所有用例,但在智能手机上,调整窗口大小并不常见,因此调整大小事件很可能来自键盘打开。这段代码未经测试,但它说明了一般思路:

let fullWindowHeight = window.innerHeight;
let keyboardIsProbablyOpen = false;

window.addEventListener("resize", function() {
  if(window.innerHeight == fullWindowHeight) {
    keyboardIsProbablyOpen = false;
  } else if(window.innerHeight < fullWindowHeight*0.9) {
    keyboardIsProbablyOpen = true;
  }
});

结合焦点/失焦事件使用可能有助于帮助(例如)检测用户按下返回按钮时键盘关闭(如@filipvkovic所指出的那样)。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接