jquery mobile如何检测手机虚拟键盘是否打开

jquery mobile how to detect if mobile virtual keyboard is opened

在移动设备中,当我打开我的页面和 select 一个输入框时,虚拟键盘是打开的,我想捕捉这个事件来完成我的工作。

移动浏览器中是否定义了任何事件处理来完成此操作?

因此,当键盘打开时,我想 运行 我的自定义函数到 show/hide 页面中的一些 UI 块。

谢谢

不确定 jQuery 移动设备是否提供了特定的内容,但简单来说 Javascript 您可以向 focus event to listen for "keyboard open" and an event listener to the blur[=14 添加一个事件侦听器=] 事件表示 "unfocus" 或您的情况 "keyboard close"。然而,如果您在键盘打开时由于先前的焦点事件而焦点不同的元素,则您必须手动处理逻辑。

首先 jQuery Mobile 没有针对这种情况的任何预定义事件处理程序。 你需要自己想办法。

Android

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

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: 
    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();
});

我猜你不会在意我的回答,因为你有更好的答案,但它是:

$(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
  }
});

this answer 中所建议,您可以使用 window.visualViewport

The visual viewport is the visual portion of a screen excluding on-screen keyboards, areas outside of a pinch-zoom area, or any other on-screen artifact that doesn't scale with the dimensions of a page.

我在几个打开键盘的设备上测量了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)

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