Ios5 iOS 5固定定位和虚拟键盘
我有一个移动网站,有一个div通过position:fixed固定在屏幕底部。在iOS5中(我正在iPodtouch上测试),所有这些都可以正常工作,直到我进入一个表单页面。当我点击一个输入字段,虚拟键盘出现时,我的div的固定位置突然丢失。现在只要键盘可见,div就会随页面滚动。单击“完成”关闭键盘后,div将恢复到屏幕底部的位置,并遵守位置:固定规则Ios5 iOS 5固定定位和虚拟键盘,ios5,css-position,virtual-keyboard,Ios5,Css Position,Virtual Keyboard,我有一个移动网站,有一个div通过position:fixed固定在屏幕底部。在iOS5中(我正在iPodtouch上测试),所有这些都可以正常工作,直到我进入一个表单页面。当我点击一个输入字段,虚拟键盘出现时,我的div的固定位置突然丢失。现在只要键盘可见,div就会随页面滚动。单击“完成”关闭键盘后,div将恢复到屏幕底部的位置,并遵守位置:固定规则 还有其他人经历过这种行为吗?这是预期的吗?谢谢。当键盘打开时,位置固定元件不会更新其位置。我发现,通过诱使Safari认为页面已经调整了大小,
还有其他人经历过这种行为吗?这是预期的吗?谢谢。当键盘打开时,位置固定元件不会更新其位置。我发现,通过诱使Safari认为页面已经调整了大小,元素将重新定位自己。这并不完美,但至少你不必担心切换到“位置:绝对”并自己跟踪变化 下面的代码只监听用户可能使用键盘的时间(由于输入被聚焦),直到听到模糊,它只监听任何滚动事件,然后执行调整大小的技巧。到目前为止,我的工作似乎还不错
var needsScrollUpdate = false;
$(document).scroll(function(){
if(needsScrollUpdate) {
setTimeout(function() {
$("body").css("height", "+=1").css("height", "-=1");
}, 0);
}
});
$("input, textarea").live("focus", function(e) {
needsScrollUpdate = true;
});
$("input, textarea").live("blur", function(e) {
needsScrollUpdate = false;
});
我找到的关于这个bug的其他答案都不适用于我。我只需将页面向上滚动34像素,即MobileSafari向下滚动的量,就可以解决这个问题。使用jquery:
$('.search-form').on('focusin', function(){
$(window).scrollTop($(window).scrollTop() + 34);
});
这显然会在所有浏览器中生效,但它可以防止它在iOS中被破坏。我在ipad上遇到了一个稍微不同的问题,虚拟键盘将我的视口推到了屏幕外。然后,在用户关闭虚拟键盘后,我的视口仍在屏幕外。在我的情况下,我做了如下事情:
var el = document.getElementById('someInputElement');
function blurInput() {
window.scrollTo(0, 0);
}
el.addEventListener('blur', blurInput, false);
这是我们用来解决ipad问题的代码。它基本上检测偏移和滚动位置之间的差异——这意味着“固定”不能正常工作
$(window).bind('scroll', function () {
var $nav = $(".navbar")
var scrollTop = $(window).scrollTop();
var offsetTop = $nav.offset().top;
if (Math.abs(scrollTop - offsetTop) > 1) {
$nav.css('position', 'absolute');
setTimeout(function(){
$nav.css('position', 'fixed');
}, 1);
}
});
以防万一,有人会像我在研究这个问题时那样,发现这个问题。我发现这条线索有助于激发我对这个问题的思考 这是我在最近的一个项目中对此的解决方案。您只需要将“targetElem”的值更改为表示标头的jQuery选择器
if(navigator.userAgent.match(/iPad/i) != null){
var iOSKeyboardFix = {
targetElem: $('#fooSelector'),
init: (function(){
$("input, textarea").on("focus", function() {
iOSKeyboardFix.bind();
});
})(),
bind: function(){
$(document).on('scroll', iOSKeyboardFix.react);
iOSKeyboardFix.react();
},
react: function(){
var offsetX = iOSKeyboardFix.targetElem.offset().top;
var scrollX = $(window).scrollTop();
var changeX = offsetX - scrollX;
iOSKeyboardFix.targetElem.css({'position': 'fixed', 'top' : '-'+changeX+'px'});
$('input, textarea').on('blur', iOSKeyboardFix.undo);
$(document).on('touchstart', iOSKeyboardFix.undo);
},
undo: function(){
iOSKeyboardFix.targetElem.removeAttr('style');
document.activeElement.blur();
$(document).off('scroll',iOSKeyboardFix.react);
$(document).off('touchstart', iOSKeyboardFix.undo);
$('input, textarea').off('blur', iOSKeyboardFix.undo);
}
};
};
由于iOS在滚动时停止DOM操作,因此修复程序有一点延迟,但它确实起到了作用…我的应用程序中出现了这个问题。以下是我如何解决这个问题的:
input.on('focus', function(){
header.css({position:'absolute'});
});
input.on('blur', function(){
header.css({position:'fixed'});
});
我只是滚动到顶部并将其定位在那里,这样iOS用户就不会注意到任何奇怪的事情。将其包装在一些用户代理检测中,以便其他用户不会获得此行为。在Github上找到此解决方案 确保您有可滚动的内容
// put in your .js file
$(window).load(function(){
window.scrollTo(0, 1);
});
// min-height set for scrollable content
<div id="wrap" style="min-height: 480px">
// website goes here
</div>
//放入.js文件
$(窗口)。加载(函数(){
滚动到(0,1);
});
//可滚动内容的最小高度设置
//网站在这里
地址栏可以折叠起来作为额外的奖励。以防有人想试试。我在一个固定的页脚上使用了以下内容,其中包含一个inputfield
<script>
$('document').ready(
function() {
if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)) {
var windowHeight = $(window).height();
var documentHeight = $(document).height();
$('#notes').live('focus', function() {
if (documentHeight > windowHeight) {
$('#controlsContainer').css({
position : 'absolute'
});
$("html, body").animate({
scrollTop : $(document).height()
}, 1);
}
});
$('#notes').live('blur', function() {
$('#controlsContainer').css({
position : 'fixed'
});
$("html, body").animate({
scrollTop : 0
}, 1);
});
}
});
</script>
$('document')。准备好了吗(
函数(){
if(navigator.userAgent.match(/Android/i)| navigator.userAgent.match(/webOS/i)| navigator.userAgent.match(/iPhone/i)| navigator.userAgent.match(/iPad/i)
||navigator.userAgent.match(/iPod/i)| navigator.userAgent.match(/BlackBerry/i)| navigator.userAgent.match(/Windows Phone/i)){
var windowHeight=$(window.height();
var documentHeight=$(document).height();
$('#notes').live('focus',function(){
如果(文档高度>窗口高度){
$('#controlsContainer').css({
位置:'绝对'
});
$(“html,body”).animate({
scrollTop:$(文档).height()
}, 1);
}
});
$('#notes').live('blur',function(){
$('#controlsContainer').css({
位置:'固定'
});
$(“html,body”).animate({
滚动顶部:0
}, 1);
});
}
});
我也有同样的问题。但我意识到,固定的位置只是延迟,而不是中断(至少对我来说)。等待5-10秒,查看div是否调整回屏幕底部。我相信这不是一个错误,而是键盘打开时的延迟响应。我已通过以下方式固定了我的Ipad主布局内容固定位置:
var mainHeight;
var main = $('.main');
// hack to detects the virtual keyboard close action and fix the layout bug of fixed elements not being re-flowed
function mainHeightChanged() {
$('body').scrollTop(0);
}
window.setInterval(function () {
if (mainHeight !== main.height())mainHeightChanged();
mainHeight = main.height();
}, 100);
这个问题真的很烦人 我结合了上面提到的一些技术,得出了以下结论:
$(document).on('focus', 'input, textarea', function() {
$('.YOUR-FIXED-DIV').css('position', 'static');
});
$(document).on('blur', 'input, textarea', function() {
setTimeout(function() {
$('.YOUR-FIXED-DIV').css('position', 'fixed');
$('body').css('height', '+=1').css('height', '-=1');
}, 100);
});
我有两个固定导航栏(页眉和页脚,使用twitter引导)。
两人在键盘打开时都表现得很奇怪,在键盘关闭后又表现得很奇怪
通过此定时/延迟修复,它可以正常工作。我仍然偶尔会发现一个小故障,但它似乎足以向客户展示它
让我知道这是否适合你。如果不是的话,我们可能会找到别的东西。谢谢。我尝试了此线程中的所有方法,但如果没有帮助,效果会更糟。 最后,我决定强制设备松开焦点:
$(<selector to your input field>).focus(function(){
var $this = $(this);
if (<user agent target check>) {
function removeFocus () {
$(<selector to some different interactive element>).focus();
$(window).off('resize', removeFocus);
}
$(window).on('resize', removeFocus);
}
});
$().focus(函数()){
var$this=$(this);
如果(){
函数removeFocus(){
$().focus();
$(窗口).off('调整大小',移除焦点);
}
$(窗口)。打开('调整大小',移除焦点);
}
});
它就像一个符咒,修复了我的粘性登录表单
请注意:
ready(function(){
/* This addresses the dreaded "fixed footer floating when focusing inputs and keybard is shown" on iphone
*
*/
if(navigator.userAgent.match(/iPhone/i)){
var allInputs = query('input,textarea,select');
var d = document, navEl = "nav";
allInputs.on('focus', function(el){
d.getElementById(navEl).style.position = "static";
});
var fixFooter = function(){
if(d.activeElement.tagName == "BODY"){
d.getElementById(navEl).style.position = "fixed";
}
};
allInputs.on('blur', fixFooter);
var b = d.body;
b.addEventListener("touchend", fixFooter );
}
});
var $window = $(window);
var initialScroll = $window.scrollTop();
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
setTimeout(function () {
$window.scrollTop($window.scrollTop() + (initialScroll - $window.scrollTop()));
}, 0);
}
<head>
...various JS and CSS imports...
<script type="text/javascript">
document.write( '<style>#footer{visibility:hidden}@media(min-height:' + ($( window ).height() - 10) + 'px){#footer{visibility:visible}}</style>' );
</script>
</head>
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
$(document).on('focus', 'input, textarea', function() {
$('header').css({'position':'static'});
});
$(document).on('blur', 'input, textarea', function() {
$('header').css({'position':'fixed'});
});
}
(function(){
var targetElem = $('.fixedElement'), // or more than one
$doc = $(document),
offsetY, scrollY, changeY;
if( !targetElem.length || !navigator.userAgent.match(/iPhone|iPad|iPod/i) )
return;
$doc.on('focus.iOSKeyboardFix', 'input, textarea, [contenteditable]', bind);
function bind(){
$(window).on('scroll.iOSKeyboardFix', react);
react();
}
function react(){
offsetY = targetElem.offset().top;
scrollY = $(window).scrollTop();
changeY = offsetY - scrollY;
targetElem.css({'top':'-'+ changeY +'px'});
// Instead of the above, I personally just do:
// targetElem.css('opacity', 0);
$doc.on('blur.iOSKeyboardFix', 'input, textarea, [contenteditable]', unbind)
.on('touchend.iOSKeyboardFix', unbind);
}
function unbind(){
targetElem.removeAttr('style');
document.activeElement.blur();
$(window).off('scroll.iOSKeyboardFix');
$doc.off('touchend.iOSKeyboardFix blur.iOSKeyboardFix');
}
})();
$(document).on('blur', 'input, textarea', function () {
setTimeout(function () {
window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
}, 0);
});
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no,height=device-height" >
height=device-height
$(select.modal).blur(function(){
$('body').scrollTop(0);
});
$("#myInput").on("focus", function () {
$("body").css("position", "fixed");
});
$("#myInput").on("blur", function () {
$("body").css("position", "static");
});
var mobileInputReposition = function(){
//if statement is optional, I wanted to restrict this script to mobile devices where the problem arose
if(screen.width < 769){
setTimeout(function(){
var parentFrame = $('#subscribe-popup-frame',window.parent.document);
var parentFramePosFull = parentFrame.position();
var parentFramePosFlip = parentFramePosFull['top'] * -1;
parentFrame.css({'position' : 'fixed', 'top' : parentFramePosFlip + 'px'});
},500);
}
}