javascript Android 键盘使用 CSS 中的单位 vh 缩小视口和元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32963400/
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
Android Keyboard shrinking the viewport and elements using unit vh in CSS
提问by Manu
I am experiencing a very strange and unique issue.
我遇到了一个非常奇怪和独特的问题。
All my pages are using vh and vw CSS units instead of px due to the nature of the project.
由于项目的性质,我所有的页面都使用 vh 和 vw CSS 单位而不是 px。
Issue: On Android tablets, when you touch the input field the default keyboard pushes the view port which is causing the page and all the elements in the page to shrink.
问题:在 Android 平板电脑上,当您触摸输入字段时,默认键盘会推送导致页面和页面中所有元素缩小的视口。
On ipad this issue does not exist since the keyboard overlaps the screen and does not push the screen.
在 ipad 上不存在此问题,因为键盘与屏幕重叠并且不会推动屏幕。
Looking for any solution to avoid the Android keyboard not to push the viewport of the browser and keep the original size.
寻找任何解决方案来避免Android键盘不推送浏览器的视口并保持原始大小。
Note: The only option i am left with is to avoid keyboard to push viewport, i won't be able to change the CSS units or use xml, manifest. These are web pages which experiencing this issue.
注意:我剩下的唯一选择是避免使用键盘推送视口,我将无法更改 CSS 单位或使用 xml、manifest。这些是遇到此问题的网页。
回答by Tyler Merle
I know this is an old question, but I had the exact same problem in my app. The solution I found was fairly simple. (My app is in Angular so I put this in the app.component's ngOnInit
function, but document.ready()
or any other "initialization complete" callback should work just fine with the proper experimentation)
我知道这是一个老问题,但我的应用程序中遇到了完全相同的问题。我找到的解决方案相当简单。(我的应用程序在 Angular 中,所以我把它放在 app.component 的ngOnInit
函数中,但是document.ready()
或任何其他“初始化完成”回调应该可以通过适当的实验正常工作)
setTimeout(function () {
let viewheight = $(window).height();
let viewwidth = $(window).width();
let viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute("content", "height=" + viewheight + "px, width=" + viewwidth + "px, initial-scale=1.0");
}, 300);
This forces the viewport meta to explicitly set viewport height, whereas hardcoding
这会强制视口元显式设置视口高度,而硬编码
<meta name="viewport"
content="width=device-width, height=device-height, initial-scale=1">
doesn't work because the device-width and device-height change when Android's soft keyboard is opened.
不起作用,因为当 Android 的软键盘打开时,设备宽度和设备高度会发生变化。
回答by MatWer
Nearly a year to late, but I want also to share my solution to this more and more important problem.
快一年了,但我也想分享我对这个越来越重要的问题的解决方案。
I created a small JS function SET which is loaded after the DOM is completed.
我创建了一个小的 JS 函数 SET,它在 DOM 完成后加载。
Every Element assigned to a special class (In this case ".pheight") doesn't resized when the viewport height decreases. It is only allowed to resize if the viewport height increases or the viewport width changes.
当视口高度降低时,分配给特殊类(在本例中为“.pheight”)的每个元素都不会调整大小。只有在视口高度增加或视口宽度改变时才允许调整大小。
So in my Applications it works perfectly!
所以在我的应用程序中它完美地工作!
var docwidth = window.innerWidth;
var docheight = window.innerHeight;
function pheigt_init() {
pheigt_set_prevent_height();
window.onresize = function() {
if (docwidth !== window.innerWidth || docheight < window.innerHeight) {
pheigt_upd_prevent_height();
}
};
}
function pheigt_set_prevent_height() {
document.querySelectorAll('.pheight').forEach(function(node) {
node.style.height = node.offsetHeight + 'px';
});
}
function pheigt_upd_prevent_height() {
document.querySelectorAll('.pheight').forEach(function(node) {
node.style.removeProperty('height');
});
setTimeout(function(){ pheigt_set_prevent_height(); }, 100);
docheight = window.innerHeight;
docwidth = window.innerWidth;
}
document.addEventListener('DOMContentLoaded', pheigt_init());
回答by Mayous
I faced the same problem recently, and it took me time to find a nice solution. I am designing a cordova app using html5, css3 and angularjs. But moreover, I want my app to fit every screen without writing tones of media queries and finally unreadable css. I started with viewport and vh, but the keyboard broke eveything.
我最近遇到了同样的问题,我花了很长时间才找到一个好的解决方案。我正在设计一个使用 html5、css3 和 angularjs 的cordova 应用程序。但此外,我希望我的应用程序适合每个屏幕,而无需编写媒体查询的音调,最终不可读的 css。我从视口和 vh 开始,但键盘破坏了一切。
So what you have to use is just a little javascript (here is jquery) like this :
所以你必须使用的只是一个像这样的小 javascript(这里是 jquery):
$("html").css({"font-size": ($(window).height()/100)+"px"});
Here you go, now you can use "rem" exactly the same way you are using "vh", except that the viewport will not affect font-size. "Rem" is set on html root font-size only and we just set it with jquery to 1% of the screen height.
好了,现在您可以使用与使用“vh”完全相同的方式使用“rem”,只是视口不会影响字体大小。“Rem”仅在 html root font-size 上设置,我们只是使用 jquery 将其设置为屏幕高度的 1%。
Hope this will help!
希望这会有所帮助!
EDIT 1 : I just faced a new problem, so I give my solution here. Most of the time, smartphones have a minimum limit for font-size. You have to change all your rem value, and divide it by 3 or 4. Then, you have to change the javascript with :
编辑 1:我刚遇到一个新问题,所以我在这里给出我的解决方案。大多数时候,智能手机都有字体大小的最小限制。您必须更改所有 rem 值,并将其除以 3 或 4。然后,您必须使用以下内容更改 javascript:
$("html").css({"font-size": ($(window).height()/25)+"px"}); /*(this is if you divide with 4)*/
It is even easier if you are using SASS, you can create a rem function which will do division for you.
如果您使用的是 SASS,那就更容易了,您可以创建一个 rem 函数来为您进行除法。
回答by Foxel
Based on Tyler's question, this is a vanilla version of the script which seems to be a bit cleaner:
基于 Tyler 的问题,这是脚本的香草版本,似乎更简洁一些:
addEventListener("load", function() {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute("content", viewport.content + ", height=" + window.innerHeight);
})
If you use it after the meta tag declaration you can even get rid of that addEventListener
:
如果您在元标记声明之后使用它,您甚至可以摆脱它addEventListener
:
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute("content", viewport.content + ", height=" + window.innerHeight);
回答by Joe Keene
In Angular 4+
在 Angular 4+
import {Meta} from "@angular/platform-browser";
constructor(private metaService: Meta){}
ngOnInit() {
this.metaService.updateTag({
name: 'viewport',
content: `height=${this.height}px, width=${this.width}px, initial-scale=1.0`
},
`name='viewport'`
);
}
回答by Ced
You could use % which doesn't seems to be affected by this issue or vw (not affected for obvious reason) even for height.
您可以使用 % ,它似乎不受此问题或 vw (由于明显原因不受影响)的影响,即使是高度也是如此。
回答by MagiK
The same problem put me off my stride. I don't found any css solution or workaround in order to solve the problem.
同样的问题让我大吃一惊。我没有找到任何 css 解决方案或解决方法来解决问题。
However, if you can use JQuery (or almost JavaScript), I have some code you can use to resolve it.
但是,如果您可以使用 JQuery(或几乎是 JavaScript),我有一些代码可以用来解决它。
var viewportHeight = $(window).height();
var viewportWidth = $(window).width();
$('body,html').css("height",viewportHeight); //if vh used in body/html too
$('.someClass').css("height",viewportHeight*0.12);// or whatever percentage you used in vh
$('#someId').css("width",viewportWidth*0.12);
Well, this is just an example, you can use the percentage, jQuery identifiers you need to.
嗯,这只是一个例子,你可以使用百分比,你需要的 jQuery 标识符。
PD: there's one tip for your info. put the code at the final of your html or inside $(document).ready(function() { });, and if you need responsive design, put it also inside orientationchange event; this way.
PD:有一个提示可以提供您的信息。把代码放在你的 html 的最后或者$(document).ready(function() { }); , 如果你需要响应式设计,也把它放在orientationchange 事件中;这边走。
$(window).on("orientationchange",function(event){ window.setTimeout(function(){
var viewportHeight = $(window).height();
var viewportWidth = $(window).width();
$('body,html').css("height",viewportHeight);
$('.someClass').css("height",viewportHeight*0.12);
$('.someClass').css("width",viewportWidth*0.09);
$('#someId').css("height",viewportHeight*0.1);
}}, 450);});
I put a 450ms Timer above because of the delay of devices doing the orientationchange.
由于设备执行方向更改的延迟,我在上面放置了一个 450ms 计时器。
Sorry for my english, cheers
对不起我的英语,干杯