Ios5 iOS 5固定定位和虚拟键盘

Ios5 iOS 5固定定位和虚拟键盘,ios5,css-position,virtual-keyboard,Ios5,Css Position,Virtual Keyboard,我有一个移动网站,有一个div通过position:fixed固定在屏幕底部。在iOS5中(我正在iPodtouch上测试),所有这些都可以正常工作,直到我进入一个表单页面。当我点击一个输入字段,虚拟键盘出现时,我的div的固定位置突然丢失。现在只要键盘可见,div就会随页面滚动。单击“完成”关闭键盘后,div将恢复到屏幕底部的位置,并遵守位置:固定规则 还有其他人经历过这种行为吗?这是预期的吗?谢谢。当键盘打开时,位置固定元件不会更新其位置。我发现,通过诱使Safari认为页面已经调整了大小,

我有一个移动网站,有一个div通过position:fixed固定在屏幕底部。在iOS5中(我正在iPodtouch上测试),所有这些都可以正常工作,直到我进入一个表单页面。当我点击一个输入字段,虚拟键盘出现时,我的div的固定位置突然丢失。现在只要键盘可见,div就会随页面滚动。单击“完成”关闭键盘后,div将恢复到屏幕底部的位置,并遵守位置:固定规则


还有其他人经历过这种行为吗?这是预期的吗?谢谢。

当键盘打开时,位置固定元件不会更新其位置。我发现,通过诱使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('调整大小',移除焦点);
}
$(窗口)。打开('调整大小',移除焦点);
}
});
它就像一个符咒,修复了我的粘性登录表单

注意:

  • 上面的JS代码只是为了表达我的想法,要执行此代码段,请使用适合您情况的值替换角括号()中的值
  • 此代码旨在与jQuery v1.10.2配合使用
  • 我有一个类似的职业选手
    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);
                }    
            }