jQuery 打开软键盘时获取视口高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23023549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 02:10:41  来源:igfitidea点击:

Get viewport height when soft keyboard is on

jqueryioscssviewport

提问by scooterlord

I've been trying to make this work for days now, with no luck, so I thought I'd share info and maybe someone comes up with a solution.

我已经尝试使这项工作好几天了,但没有运气,所以我想我会分享信息,也许有人会提出解决方案。

I want to get the exact viewport size when the soft keyboard is up. I am currently using the following code on the header in order for the site to be responsive:

我想在软键盘启动时获得确切的视口大小。我目前正在标题上使用以下代码,以便网站响应:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>

What I realized is that when the soft keyboard comes up, it uses the device height as the viewport height and pushes the rest of the site upwards - which makes me assume that it's getting it's height from the width=device-width option.

我意识到当软键盘出现时,它使用设备高度作为视口高度并将网站的其余部分向上推 - 这让我假设它是从 width=device-width 选项中获取它的高度。

Using the following code after initiating the soft keyboard:

启动软键盘后使用以下代码:

setTimeout(function() {  
    viewport = document.querySelector("meta[name=viewport]");
    viewport.setAttribute('content', 'height=auto');
}, 300)

And then getting the height using jquery shows CORRECT results on Android - aka the visible viewport size WITHOUT the virtual keyboard, but not on iOS. I am getting a random number, which I assume stems from the rest of the meta tag not existing, so I am getting a zoomed-in version of the website along with a number like 75 or 100 (on iphone 4s)

然后使用 jquery 获取高度在 Android 上显示正确的结果 - 也就是没有虚拟键盘的可见视口大小,但不是在 iOS 上。我得到一个随机数,我认为它源于不存在的元标记的其余部分,所以我得到了网站的放大版本以及像 75 或 100(在 iphone 4s 上)这样的数字

I also tried creating a fixed element after bringing the keyboard up, making it use the viewport height with top:0; and bottom:0; attributes, but I still get the original height.

我还尝试在打开键盘后创建一个固定元素,使其使用 top:0 的视口高度;和底部:0; 属性,但我仍然得到原来的高度。

What comes closer to this, is setting the viewport meta tag height to a fixed value, that can be picked up by jquery's $(window).height(), which means that the meta tag actually makes a difference after initiating the keyboard, but there is no true value for a fixed height.

更接近于此的是,将视口元标记高度设置为一个固定值,该值可以由 jquery 获取$(window).height(),这意味着元标记在启动键盘后实际上有所不同,但没有真正的固定值高度。

I've seen lots of topics around this, but none with a solution. Anyone that has a solution for this?

我已经看到很多关于这个的话题,但没有一个有解决方案。任何有解决方案的人?

采纳答案by scooterlord

In the view I wanted to take the height of the remaining screen after the virtual keyboard was on, I was using an absolutely overflown elementthat covered the whole screen using screen height and the content of the whole page was inside of it. As a result, the virtual keyboard was opening on TOP of the overflown element, without changing its dimensions.

在我想在虚拟键盘打开后获取剩余屏幕的高度的视图中,我使用了一个绝对溢出的元素,该元素使用屏幕高度覆盖整个屏幕,并且整个页面的内容都在其中。结果,虚拟键盘在溢出元素的顶部打开,而不改变其尺寸。

To fix the specific problem, all I had was change the position of this element to static and remove the overflow when the virtual keyboard was opened - actually ios changes to THIS behaviour by default when issuing he virtual keyboard (changes elements to static position) and this is why the fixed elements become static.

为了解决特定问题,我所做的只是将此元素的位置更改为静态并在打开虚拟键盘时删除溢出 - 实际上,当发出虚拟键盘(将元素更改为静态位置)和这就是固定元素变成静态的原因。

I hope this helps.

我希望这有帮助。

回答by Steve Buzonas

The viewport dimensions come from the size of the UIWebViewelement.

视口尺寸来自UIWebView元素的大小。

As mentioned in the previous answerthere are two ways to handle adapting to the on screen keyboard. You can resize the view or adjust the content insets.

正如前面的回答中提到的,有两种方法可以适应屏幕键盘。您可以调整视图大小或调整内容插入。

The dimensions of the viewport on iOS are reporting the size of the view so resizing would adjust the viewport. Safari adjusts the insets and keeps the view the same size so the viewport does not change.

iOS 上视口的尺寸报告视图的大小,因此调整大小会调整视口。Safari 调整插图并保持视图大小相同,因此视口不会改变。

If you were to make assumptions that touch devices generally utilize on screen input rather than external keyboards you can programmatically adjust the size on your own by taking the device height or width depending on orientation and factor in a multiplier for portion of the screen consumed by the on screen keyboard.

如果您假设触摸设备通常在屏幕输入而不是外部键盘上使用,您可以通过根据方向和因素来获取设备高度或宽度来自行调整大小在屏幕键盘上。

I utilize a viewport class to act as a proxy to give me most likely real viewport dimensions rather than browser reported and binds to input elements to track state of input elements and orientation changes to dynamically modify the multiplier applied when requesting the viewport dimensions.

我利用视口类作为代理来为我提供最有可能的真实视口尺寸,而不是浏览器报告的并绑定到输入元素以跟踪输入元素的状态和方向变化,以动态修改请求视口尺寸时应用的乘数。

回答by CamoNunez

I've found myself with the same problem and after a while mixing CSS and a little bit of javascript, I found a solution.

我发现自己遇到了同样的问题,在混合 CSS 和一点点 javascript 之后,我找到了一个解决方案。

Notes:

笔记:

  • I used jQuery and SCSS
  • I preferred to hide the element instead of changing its position (simple and effective)
  • The element is shown if the virtual keyboard is closed but the input is still on focus. For this I wrapped the css rule in a media query @media screen and (min-aspect-ratio: 11/16). 11/16 because it's less than the common 9/16 ratio (the presence of the virtual keyboard increases this ratio then the rule is applied)
  • 我使用了 jQuery 和 SCSS
  • 我更喜欢隐藏元素而不是改变它的位置(简单有效)
  • 如果虚拟键盘关闭但输入仍处于焦点上,则显示该元素。为此,我将 css 规则包装在媒体查询@media screen 和 (min-aspect-ratio: 11/16) 中。11/16 因为它小于常见的 9/16 比率(虚拟键盘的存在会增加此比率,然后应用规则)

The solution:

解决方案:

First, the script (using jQuery):

首先,脚本(使用jQuery):

$(document).on('focus', 'input, textarea', function(){
    $('body').addClass("fixfixed");
});

$(document).on('blur', 'input, textarea', function(){
    $('body').removeClass("fixfixed");
});

So, while the user focuses on a text input and the virtual keyboard is open, the body has a 'fixfixed' class.

因此,当用户专注于文本输入并且虚拟键盘处于打开状态时,主体具有“fixfixed”类。

Then, the CSS (I'm using SCSS):

然后,CSS(我使用 SCSS):

.fixfixed{
  @media screen and (min-aspect-ratio: 11/16) {
    .bottomThingToHideWhenVirtualKeyboardIsShown{
      opacity: 0;
      pointer-events: none;
    }
  }
}

And that's it!

就是这样!

Hope it helps someone!

希望它可以帮助某人!

回答by Will Kru

I came up with this hack:

我想出了这个黑客:

var storedWidth = 0;
var storedHheight = 0;

function onResize() {

  var windowWidth = $(window).width();
  var windowHeight = $(window).height();
  var screenWidth = screen.width || windowWidth;
  var screenHeight = screen.height || windowHeight;
  var width, height;

  if(screenWidth < screenHeight) {
    if(windowWidth > storedWidth) storedWidth = windowWidth;
    if(windowHeight > storedHeight) storedHeight = windowHeight;
    width = storedWidth;
    height = storedHeight;
  }else {
    width = windowWidth;
    height = windowHeight;
  }

  //use width and height from here

}

Now this would fail in two cases:

现在这将在两种情况下失败:

  • screen.width/screen.height not being supported; it would fallback to the erroneous jquery dimensions. In my case, the soft keyboard made the height smaller than the width while in portrait mode, so the jQuery dimensions resulted in a false landscape mode and thus showing the 'rotate your device' message.

  • the page is opened with the soft keyboard opened, which I think is moot. Also after hiding it, the largest height is stored so things will be fixed after that.

  • 不支持 screen.width/screen.height;它会回退到错误的 jquery 维度。就我而言,软键盘在纵向模式下使高度小于宽度,因此 jQuery 尺寸导致错误的横向模式,从而显示“旋转您的设备”消息。

  • 该页面是在打开软键盘的情况下打开的,我认为这是没有实际意义的。同样在隐藏它之后,最大的高度被存储,所以之后的事情将被修复。

Note:

笔记:

  • window.innerWidth/window.innerHeight could be used to ditch the jQuery dependency

  • above code is to fix the keyboard issue in portrait mode, but same solution could be used for landscape mode

  • window.innerWidth/window.innerHeight 可用于抛弃 jQuery 依赖

  • 上面的代码是为了解决纵向模式下的键盘问题,但同样的解决方案可以用于横向模式

回答by James Hafner

This solution is a bit convoluted, but it might work...

这个解决方案有点复杂,但它可能有效......

  1. Detect whether or not the keyboard is active.
  2. Grab the viewport width/height
  3. Subtract the height of the keyboard.
  1. 检测键盘是否处于活动状态。
  2. 获取视口宽度/高度
  3. 减去键盘的高度。

回答by Rivera

Just to give you an idea, when the keyboard appears on iOS by default it does nothing on the underlying scrollview.

只是给你一个想法,当键盘默认出现在 iOS 上时,它对底层滚动视图没有任何作用。

If your content is shown in a custom UIWebView, it is up to the programmer to either:

如果您的内容显示在 custom 中UIWebView,则由程序员决定:

  • Resize the scrollview to avoid getting unreachable content under the keyboard.

  • Adjust the scrollview's content insets (recommended). The scrollview size stays the same but a "border" is added to the bottom so the user can scroll all to all the contents.

  • 调整滚动视图的大小以避免在键盘下无法访问内容。

  • 调整滚动视图的内容插入(推荐)。滚动视图大小保持不变,但在底部添加了一个“边框”,以便用户可以滚动到所有内容。

I am not sure how either solution affects the viewport, but your could try both.

我不确定这两种解决方案如何影响viewport,但您可以同时尝试。

If your web content is being presented by Safari however, Apple adjusts the insets for you.

但是,如果您的网页内容由 Safari 呈现,Apple 会为您调整插图。

回答by guest271314

Piece attempts to return approximate window.innerWidth, window.innerHeightvalues at ios6 ua; jquery utilized for selectors and .on(). Not certain about detecting ios device keyboard events portion; see resources links

件试图返回近似window.innerWidthwindow.innerHeight在iOS6的UA值; jquery 用于选择器和.on(). 不确定检测 ios 设备键盘事件部分;查看资源链接

Try

尝试

css

css

html {
    height : 100vh;
    width : 100vw;
}

js

js

$(function() {    
    if (/ipad|iphone/gi.test(window.navigator.userAgent)) {
    var events = "abort blur focus input scroll submit touchstart touchmove";
    $("form, input").on(events, function(e) {
      return (function(window, elem, w, h) {
               var vh = window.getComputedStyle(elem,null).getPropertyValue(h);
               var vw = window.getComputedStyle(elem,null).getPropertyValue(w);
               var vwh = { 
                           "documentWidth": vw, 
                           "documentHeight": vh, 
                           "windowInnerWidth": window.innerWidth, 
                           "windowInnerHeight": window.innerHeight
                         };
               console.log(vwh);
               var _vwh = document.getElementById("vwh");
               _vwh.innerHTML = JSON.stringify(vwh)
               return vwh 
              }(window, document.documentElement, "width", "height"));
    }).focus();
    };
})

jsfiddle http://jsfiddle.net/guest271314/Pv3N2/

jsfiddle http://jsfiddle.net/guest271314/Pv3N2/

resources

资源

https://developer.mozilla.org/en-US/docs/Web/API/Window.innerHeight

https://developer.mozilla.org/en-US/docs/Web/API/Window.innerHeight

http://www.w3.org/TR/2013/CR-css3-values-20130730/#vh-unit

http://www.w3.org/TR/2013/CR-css3-values-20130730/#vh-unit

how to handle key events in iphone

如何处理iphone中的关键事件

https://coderwall.com/p/xuawwwResponding to Keyboard Events on iOS

https://coderwall.com/p/xuawww在 iOS 上响应键盘事件

http://looksok.wordpress.com/2013/02/02/ios-tutorial-hide-keyboard-after-return-done-key-press-in-uitextfield/iOS tutorial: hide keyboard after return / done key press in UITextField

http://looksok.wordpress.com/2013/02/02/ios-tutorial-hide-keyboard-after-return-done-key-press-in-uitextfield/iOS 教程:返回/完成按键后隐藏键盘用户界面文本字段

https://developer.apple.com/library/safari/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/InteractiveControl/InteractiveControl.html#//apple_ref/doc/uid/TP40008032-CH16

https://developer.apple.com/library/safari/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/InteractiveControl/InteractiveControl.html#//apple_ref/doc/uid/TP40008032-CH16

http://www.quirksmode.org/mobile/viewports2.html

http://www.quirksmode.org/mobile/viewports2.html