检测虚拟键盘和硬件键盘的区别

35

我已经思考了一段时间,但无法想出解决方法。有没有办法检测用户使用虚拟(软件)键盘还是传统的(硬件)键盘?

新的Windows Surface在封面上有自己的键盘,对于Android/iPad,有大量不同的蓝牙键盘。

那么,你们有什么意见吗?
我的目标是针对Android、IOS和Windows平板电脑/手机。


动机:(非常主观)

在为平板电脑/智能手机开发Web应用程序时,我明白在许多情况下使用JavaScript键盘比使用操作系统的软件键盘更容易。

假设你想输入PIN码。而不是让键盘占据半个屏幕:

软件(操作系统)键盘:

|----------------|
|    [ input]    |
|                |
|----------------|
|  1  2  3  4  5 |
|  6  7  8  9  0 |
|----------------|

JavaScript键盘:

|----------------|
|    [ input]    |
|    | 1 2 3|    |
|    | 4 5 6|    |
|    |_7_8_9|    |
|                |
|                |
|----------------|
如果你需要处理大量的输入,也许你想要创建一个拥有输入框并使用软键盘的叠加 div
|----------------|
| P1 P2    P3 P4 |
| [inp 1][inp 2] |
|----------------|
|    KEYBOARD    |
|                |
|----------------|

但是如果用户有自己的硬件键盘,我们希望直接在原地进行内联编辑。


我在Stack Overflow上找到了这篇文章:iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari? ... 但是它似乎只在iOS上有效-不确定浏览器是否支持。


1
也许这篇文章可以帮到你:https://dev59.com/kXE85IYBdhLWcg3w1HGF - rahul
1
我可以问一下为什么吗?只是好奇。 - epascarello
4
就我个人而言,我将采用不同的方法 - 对于您提供的示例用例,我将阻止输入框上的焦点事件,并始终显示JS键盘,同时监听键盘事件以捕获按下的数字键。这意味着在移动设备上不应显示虚拟键盘,在配有硬件键盘的PC和其他设备上,用户仍将能够使用它来输入数字。 - DaveRandom
3
不歧视法律合规方面怎么样?这个系统能否处理口述、鼠标移动或者通过眼动跟踪输入的信息? - Anko
1
我真的不认为你应该这样做。软件键盘是任何触摸屏界面中最基本的元素之一——用户可以理解它的工作原理,它也与操作系统的辅助功能紧密集成。无论你做得多好,你都不会比现有的软件键盘在所有平台上更直观和易于访问。 - Jordan Gray
显示剩余7条评论
6个回答

22

我认为最好的方法是将HTML5表单属性与可选的虚拟键盘链接结合使用。

HTML5表单属性可以用于触发不同类型的键盘。例如,<input type="email"><input type="number"><input type="tel">将在iOS上触发相应的键盘类型(不确定Android/WinPho/其他是否也是如此),使用户更容易输入数据。

如果需要,您还可以在文本字段下提供一个按钮来触发自定义数字键盘,以适应旧的不符合HTML5标准的移动浏览器。这些浏览器将把新的HTML5字段显示为标准文本字段。

您可以使用浏览器嗅探来检测移动浏览器,但不要忘记它们仍然支持诸如蓝牙键盘之类的东西。另外,嗅探还存在一个问题,就是肯定会错过一些浏览器,并错误地检测其他浏览器,因此您不应该仅依赖它。


我想制作一个LaTeX虚拟键盘。您可以按下“矩阵”、“积分”、“双重积分”等按钮。使用该键盘,我可以选择定界符的类型等。该键盘已经很大了...在移动设备上,虚拟键盘会妨碍操作。也许是我的问题... :-( - André Caldas

8

我认为覆盖默认的屏幕键盘不是一个好主意,我建议采用Jani提出的 - 虚拟键盘也可以适应。

但是我确信可以通过resize事件和字段聚焦或者监视window.innerHeight(或其他[a-z]*Height)来检测大多数键盘,并比较字段聚焦前后的值。

这是一个奇怪的特性检测案例,所以需要进行充分的实验和测试。如果我是你,我不会这么做。


3
截至2017年11月20日,最有效的解决方案是检测一个具有视口高度单位(vh)的
元素高度的变化,以跨Chrome / Safari等平台,在Android和iOS上都能使用。
然后,在任何输入/文本框的模糊/焦点更改时,检查该
元素是否比模糊/焦点事件前少30%的高度(像素)。
CSS:
#height-div{height: 10vh;}

jQuery:

$(document).ready(function() {
    var initialHeight = $("#height-div").height();//gives current height in pixels! We save it for later comparisons 
}

现在,这里有一个魔法:

$("input, textarea").focus(function(){
        setTimeout(function(){
            if((initialHeight*0.7) > $("#height-div").height()){//if the current viewport height is smaller than 70% of the original size, it means that the keyboard is up
                //ENTER YOUR LOGIC HERE
            }else if((initialHeight*0.7) < parent.$submit.height()){//if the current viewport height is larger than 70% of the original size, it means that the keyboard is down
            //ENTER YOUR LOGIC HERE
            }
        },500);
});

$("input, textarea").blur(function(){
        setTimeout(function(){
            if((initialHeight*0.7) > $("#height-div").height()){//if the current viewport height is smaller than 70% of the original size, it means that the keyboard is up
                //ENTER YOUR LOGIC HERE
            }else if((initialHeight*0.7) < parent.$submit.height()){//if the current viewport height is larger than 70% of the original size, it means that the keyboard is down
            //ENTER YOUR LOGIC HERE
            }
        },500);
});

1
30%只是猜测。看起来这种方法很脆弱。 - adi518
2
  1. Android设备上的键盘可以自定义为各种大小。
  2. 用户可以旋转手机。
  3. 用户可以使用分屏功能。
遗憾的是,这种方法并不完全可靠。
- Kamil Bęben

1

可能无法检测到键盘。但我建议尝试检测用户是否使用移动浏览器。因为几乎所有具有本地虚拟键盘的设备都在移动浏览器上运行。

这里有一个使用jquery的小脚本

如果他们不是移动设备,请呈现标准输入字段。

如果他们是移动设备,请勿显示输入字段(以便他们不会得到虚拟键盘),而是使用jquery更新隐藏字段或列表,当他们点击您的pinpad按钮时。


我有一台没有键盘的平板电脑,运行着几乎正常的Windows 7安装程序。我使用与PC上相同的浏览器,因此这对我来说不适用。不过还是谢谢你的指点。 - Kendall Frey

0

前几天我遇到了一个新的问题,有一个很好的答案可能会对您的键盘问题有所帮助。

jquery hover(touch)超时

本质上,它使用了一个JQuery函数,如果能够创建触摸事件,则返回布尔值。

$(document).ready(function() {

    function hasTouch() {
        try {
           document.createEvent("TouchEvent");
           return true;
        } catch (e) {
           return false;
        }    
    }

    var touchPresent = hasTouch();
});

TouchEvent 可以在没有触摸屏的设备上创建。 - sean
hasTouch() !== hasVirtualKeyboard()。 考虑带触摸屏的可转换笔记本电脑。 - Aidin

0

WURFL 是一个服务器端框架,可以提供有关请求设备功能的大量信息。使用 WURFL,您的应用程序将能够为各种设备/设备组提供优化的输出/标记。

最简单的场景之一是区分桌面、平板电脑和智能手机。

数据库(XML 文件)定期更新,并且可用于 Java、PHP 和 .NET 的官方 API。


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