Reputation: 185
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
Upvotes: 10
Views: 25555
Reputation: 5662
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/
Upvotes: 0
Reputation: 53
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
}
});
Upvotes: 3
Reputation: 6769
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.
Upvotes: 13
Reputation: 3189
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: http://stackoverflow.com/a/9039885/177710
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();
});
Upvotes: 22
Reputation: 5683
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.
Upvotes: 2