jquery mobile how to detect if mobile virtual keyboard is opened
Asked Answered
C

5

10

In mobile device, when I open my page and select an inputbox, the virtual keyboard is open, and I want to catch this event to do my job.

Is there any event handling defined in mobile browser to accomplish this?

So when the keyboard is open, I d like to run my custom function to show/hide some UI blocks in the page.

Thanks

Connie answered 13/12, 2017 at 16:47 Comment(0)
G
22

First jQuery Mobile does not have any pre-defined event handler for this case. You will need to figure out the way yourself.

Android

When virtual keyboard is open, it fires windows resize event. So you can check if the sum of windows width and height changed to detect keyboard is open or not.

iOS

This does not fire resize event, so simply bind focus and blur event as mentioned by @RamizWachtler

So I have some codes for your here:

You just add your own handling code into onKeyboardOnOff() function.

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://mcmap.net/q/48374/-detect-if-device-is-ios
    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();
});
Guarantor answered 13/12, 2017 at 17:11 Comment(3)
Oh.. awsome! This is very nice answer with detailed code. THanks a lot!Connie
Can you help me to answer my another question: #47800685Connie
nice clean solution @GuarantorPerse
A
13

As suggested in this answer, you can make use of 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.

I measured the difference between window.screen.height and window.visualViewport.height on several devices with the keyboard open and it is always more than 300px.

So you can do something like this:

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)

You should keep in mind that this solution might not work in all cases because it relies heavily on the assumption that the height of all devices' keyboards is approximately the same. Of course, you can tweak the hard-coded value but, as you can see, this is not a bulletproof solution.

Apure answered 10/2, 2021 at 15:18 Comment(0)
H
3

I guess you won't care about my answer because you've got a better one but here it is:

$(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
  }
});
Hydrolysis answered 15/11, 2019 at 19:4 Comment(0)
S
2

Not sure if there is something specific provided by jQuery mobile, but in plain Javascript you could add an event listener to the focus event to listen for "keyboard open" and an event listener to the blur event which indicates the "unfocus" or in your case "keyboard close". Nevertheless, you'd have to manually handle the logic, if you focus a different element while the keyboard is open due a previous focus event.

Sacred answered 13/12, 2017 at 16:53 Comment(1)
thanks for your answer. I just accept another answer as it has detailed code attached.Connie
A
0

You'll need to check browser support, since it's new, but:

navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {
  const { x, y, width, height } = event.target.boundingRect;
  console.log('Virtual keyboard geometry changed:', x, y, width, height);
});

https://developer.chrome.com/docs/web-platform/virtual-keyboard/

Apperceive answered 11/5 at 2:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.