我遇到了一个非常奇怪和独特的问题。
由于项目的性质,我的所有页面都使用vh和vw CSS单元而不是px。
问题:在Android平板电脑上,当您触摸输入字段时,默认键盘会推动视口,这会导致页面和页面中的所有元素缩小。
在ipad上,由于键盘与屏幕重叠并且没有按下屏幕,因此该问题不存在。
寻找任何解决方案,以避免Android键盘不要推动浏览器的视口并保持原始大小。
注意:我唯一选择的选项是避免键盘按下视口,我将无法更改CSS单位或使用xml,manifest。这些是遇到此问题的网页。
答案 0 :(得分:19)
我知道这是一个老问题,但我在我的应用中遇到了完全相同的问题。我发现的解决方案相当简单。 (我的应用程序是在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);
这会强制视口元显式设置视口高度,而硬编码
<meta name="viewport"
content="width=device-width, height=device-height, initial-scale=1">
不起作用,因为打开Android软键盘时设备宽度和设备高度会发生变化。
答案 1 :(得分:2)
基于泰勒的问题,这是脚本的原始版本,似乎更简洁:
addEventListener("load", function() {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute("content", viewport.content + ", height=" + window.innerHeight);
})
如果您在元标记声明之后使用它,甚至可以摆脱该addEventListener
:
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute("content", viewport.content + ", height=" + window.innerHeight);
答案 2 :(得分:2)
这是一个更完整的解决方案,其中考虑了屏幕方向的更改:
// Original viewport definition, note the "id" that I use to modify the viewport later on:
<meta name="viewport" id="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<script>
// Global boolean variable that holds the current orientation
var pageInPortraintMode;
// Listen for window resizes to detect orientation changes
window.addEventListener("resize", windowSizeChanged);
// Set the global orientation variable as soon as the page loads
addEventListener("load", function() {
pageInPortraintMode = window.innerHeight > window.innerWidth;
document.getElementById("viewport").setAttribute("content", "width=" + window.innerWidth + ", height=" + window.innerHeight + ", initial-scale=1.0, maximum-scale=1.0, user-scalable=0");
})
// Adjust viewport values only if orientation has changed (not on every window resize)
function windowSizeChanged() {
if (((pageInPortraintMode === true) && (window.innerHeight < window.innerWidth)) || ((pageInPortraintMode === false) && (window.innerHeight > window.innerWidth))) {
pageInPortraintMode = window.innerHeight > window.innerWidth;
document.getElementById("viewport").setAttribute("content", "width=" + window.innerWidth + ", height=" + window.innerHeight + ", initial-scale=1.0, maximum-scale=1.0, user-scalable=0");
}
}
</script>
答案 3 :(得分:1)
我最近遇到了同样的问题,我花了很多时间找到一个很好的解决方案。 我正在使用html5,css3和angularjs设计一个cordova应用程序。而且,我希望我的应用程序适合每个屏幕,而无需编写媒体查询的音调,最后无法读取css。我开始使用viewport和vh,但键盘打破了eveything。
所以你必须使用的只是一个小javascript(这里是jquery)像这样:
$("html").css({"font-size": ($(window).height()/100)+"px"});
在这里,你现在可以使用&#34; rem&#34;与您使用&#34; vh&#34;完全相同,只是视口不会影响字体大小。 &#34;雷姆&#34;仅在html root font-size上设置,我们只需将jquery设置为屏幕高度的1%。
希望这会有所帮助!
编辑1: 我刚遇到一个新问题,所以我在这里提出解决方案。大多数情况下,智能手机对字体大小有最低限制。 您必须更改所有rem值,并将其除以3或4。 然后,您必须使用以下内容更改javascript:
$("html").css({"font-size": ($(window).height()/25)+"px"}); /*(this is if you divide with 4)*/
如果你使用SASS更容易,你可以创建一个rem功能,为你做分工。
答案 4 :(得分:0)
在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'`
);
}
答案 5 :(得分:0)
您可以使用似乎不受此问题影响的%或vw(由于明显的原因而不受影响),即使身高也是如此。
答案 6 :(得分:0)
快一年到晚了,但我也想分享我对这个越来越重要的问题的解决方案。
我创建了一个小的JS函数SET,该函数在DOM完成后加载。
当视口高度减小时,分配给特殊类(在这种情况下为“ .pheight”)的每个元素都不会调整大小。仅当视口高度增加或视口宽度改变时才允许调整大小。
因此在我的应用程序中,它可以完美运行!
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());
答案 7 :(得分:0)
也许需要使用函数刷新视口高度(或仅高度)?
const reference = useRef();
function avoidKeyboard(){
setTimeout(
()=>{reference.current.querySelector("#win").style.height = "calc(100vh)"}
,2000)
}
return (
<ref={reference} div>
<input type="text" id="win" onFocus={avoidKeyboard} onBlur={avoidKeyboard}/>
</div>
)
答案 8 :(得分:-1)
同样的问题使我摆脱了困境。我没有找到任何css解决方案或解决方法来解决问题。
但是,如果您可以使用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);
嗯,这只是一个例子,你可以使用你需要的百分比,jQuery标识符。
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);});
由于设备进行方向更改的延迟,我上面放了一个450ms的计时器。
抱歉我的英文, 欢呼声