【发布时间】:2018-05-27 15:40:31
【问题描述】:
在移动设备中,当我打开我的页面并选择一个输入框时,虚拟键盘是打开的,我想捕捉这个事件来完成我的工作。
移动浏览器中是否定义了任何事件处理来完成此操作?
所以当键盘打开时,我想运行我的自定义函数来显示/隐藏页面中的一些 UI 块。
谢谢
【问题讨论】:
在移动设备中,当我打开我的页面并选择一个输入框时,虚拟键盘是打开的,我想捕捉这个事件来完成我的工作。
移动浏览器中是否定义了任何事件处理来完成此操作?
所以当键盘打开时,我想运行我的自定义函数来显示/隐藏页面中的一些 UI 块。
谢谢
【问题讨论】:
我猜你不会在意我的答案,因为你有一个更好的答案,但它是:
$(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。
视觉视口是屏幕的视觉部分,不包括屏幕键盘、捏拉缩放区域之外的区域或任何其他不随页面尺寸缩放的屏幕工件。
我在几个打开键盘的设备上测量了window.screen.height 和window.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)
您应该记住,此解决方案可能不适用于所有情况,因为它严重依赖于所有设备键盘高度大致相同的假设。当然,您可以调整硬编码的值,但正如您所见,这不是万无一失的解决方案。
【讨论】:
First jQuery Mobile 没有针对这种情况的任何预定义事件处理程序。 你需要自己想办法。
安卓
当虚拟键盘打开时,它会触发窗口调整大小事件。 因此您可以检查窗口宽度和高度的总和是否更改以检测键盘是否打开。
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: 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();
});
【讨论】: