jQuery Mobile如何检测移动虚拟键盘是否已打开

9
在移动设备上,当我打开我的页面并选择一个输入框时,虚拟键盘会弹出,我想捕获这个事件来完成我的工作。
在移动浏览器中是否定义了任何事件处理来实现这一点?
所以当键盘打开时,我想运行我的自定义函数来显示/隐藏页面中的一些UI块。
谢谢
4个回答

22

首先,jQuery Mobile没有为此情况定义任何预定义事件处理程序。 您需要自己找出方法。

Android

当虚拟键盘打开时,它会触发窗口大小调整事件。 因此,您可以检查窗口宽度和高度之和是否更改以检测键盘是否打开。

iOS

这不会触发调整大小事件,因此只需如@RamizWachtler所述绑定焦点和模糊事件即可。

这里有一些代码:

您只需将自己的处理代码添加到onKeyboardOnOff()函数中即可。

function onKeyboardOnOff(isOpen) {
    // Write down your handling code
    if (isOpen) {
        // keyboard is open
    } else {
        // keyboard is closed
    }
}

var originalPotion = false;
$(document).ready(function(){
    if (originalPotion === false) originalPotion = $(window).width() + $(window).height();
});

/**
 * Determine the mobile operating system.
 * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
 *
 * @returns {String}
 */
function getMobileOperatingSystem() {
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;

      // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
        return "winphone";
    }

    if (/android/i.test(userAgent)) {
        return "android";
    }

    // iOS detection from: https://dev59.com/EGox5IYBdhLWcg3wr2To#9039885
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
        return "ios";
    }

    return "";
}

function applyAfterResize() {

    if (getMobileOperatingSystem() != 'ios') {
        if (originalPotion !== false) {
            var wasWithKeyboard = $('body').hasClass('view-withKeyboard');
            var nowWithKeyboard = false;

                var diff = Math.abs(originalPotion - ($(window).width() + $(window).height()));
                if (diff > 100) nowWithKeyboard = true;

            $('body').toggleClass('view-withKeyboard', nowWithKeyboard);
            if (wasWithKeyboard != nowWithKeyboard) {
                onKeyboardOnOff(nowWithKeyboard);
            }
        }
    }
}

$(document).on('focus blur', 'select, textarea, input[type=text], input[type=date], input[type=password], input[type=email], input[type=number]', function(e){
    var $obj = $(this);
    var nowWithKeyboard = (e.type == 'focusin');
    $('body').toggleClass('view-withKeyboard', nowWithKeyboard);
    onKeyboardOnOff(nowWithKeyboard);
});

$(window).on('resize orientationchange', function(){
    applyAfterResize();
});

哦,太棒了!这是非常好的答案,附有详细的代码。非常感谢! - Wilson Breiner
你能帮我回答另一个问题吗:https://dev59.com/fKfja4cB1Zd3GeqPwoDQ - Wilson Breiner
优美的干净解决方案 @Codemole - hengsok

10

这个答案中所建议的,您可以利用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

不确定 jQuery mobile 是否提供了特定的功能,但在普通的 JavaScript 中,您可以添加一个事件监听器到 focus 事件来监听 "键盘打开",并添加一个事件监听器到 blur 事件,该事件表示 "取消聚焦" 或在您的情况下是 "键盘关闭"。无论如何,如果您在键盘打开的情况下通过先前的 focus 事件聚焦到另一个元素,您都必须手动处理逻辑。


1
谢谢您的回答。我刚刚接受了另一个答案,因为它附带了详细的代码。 - Wilson Breiner

2

我猜你不会在意我的回答,因为你已经有一个更好的答案了,但是这是我的回答:

$(document).on('focus blur', 'select, textarea, input', function(e){
  if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ){
    //your function
  }
  else{
    //the opposite think you want to do
  }
});

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