清姿
IN A GOOD WAY

问题说明

移动端web的footer常常设计为fixed布局,但是在页面键盘被拉起时fixed的布局会出现问题,自己试了下,在较低版本ios和部分安卓机上会有此问题。具体问题看图示:

<body class="layout-fixed">
    
    <!-- 可以滚动的区域 -->
    <main>
       <input type="text" placeholder="Footer..."/>
        <button class="submit">提交</button>
    </main>
    
    <!-- fixed定位的底部 -->
    <footer>
        
    </footer>
</body>

样式:

header, footer, main {
    display: block;
}

footer {
    position: fixed;
    height: 34px;
    left: 0;
    right: 0;
    bottom: 0;
}

main {
    margin-bottom: 34px;
    height: 2000px;
}

 

蓝色的footer是fixed定位,没有唤起软键盘的时候一切正常。

唤起软键盘,在低版本ios里面就变成:(此问题在iphone4[ios7.1.2]出现,iphone6[ios9.3.1]已经修复)

这个是滑动了一部分页面的效果,footer不听话了,没有留在最底部,跑中间了。

在某些安卓里面(如锤子SM705,安卓4.4.2)看这样:

footer紧贴软键盘,遮挡后面的区域。

产生原因:

键盘被拉起之后,fixed定位失效了,会跟随页面滚动,类似absolute了。布局乱了。

解决方法:

1.使用iscroll.js解决,库已经修复了这些问题

2.问题是由于滚动区域可以滚动引起的,那么就指定main为可滚动区域,就不会影响到footer了:

改动:

<body class="layout-fixed">
    
    <!-- 可以滚动的区域 -->
    <main>
        <div class="content">
            <input type="text" placeholder="Footer..."/>
            <button class="submit">提交</button>
        </div>
    </main>
    
    <!-- fixed定位的底部 -->
    <footer>
        
    </footer>
</body>
footer {
    position: fixed;
    height: 34px;
    left: 0;
    right: 0;
    bottom: 0;
}

main {
    /* main绝对定位,进行内部滚动 */
    position: absolute;
    bottom: 34px;
    overflow-x:auto;
    overflow-y: scroll;
}

main .content {
    height: 2000px;
}

这样改了之后又有一个问题,就是滑动在手指离开触屏之后会停,如果想恢复之前的特性,还需要做些处理:

main {
    /* main绝对定位,进行内部滚动 */
    position: absolute;
    bottom: 34px;
    overflow-y: scroll;
    /* 增加该属性 */
    -webkit-overflow-scrolling: touch;
}

但在 Android2.3+ 中,因为不支持 overflow-scrolling ,因此部分浏览器内滚动会有不流畅的卡顿。

3.其实还有更直接的解决方案,就是,在focus时给另外一个视图(就是把footer隐藏掉)不显示footer,在失去焦点时再显示回来。这个虽然说简单粗暴,但最有效方便。

4.另外的解决方案就是用js动态控制footer的样式,和3的思路类似。需要加一段js,让原来的元素变成absolute,失去焦点的时候再改回去:

.fixfixed {
position:absolute;
}
$(document)
    .on('focus', 'input', function(e) {
        $this.addClass('fixfixed');
    })
    .on('blur', 'input', function(e) {
        $this.removeClass('fixfixed');
    });

也可以改成static。

5.思路类似的方法

    $(document)
        .on('focus','input',function(e){  
            $('#viewport').height($(window).height()+'px');  
        })
        .on('blur','input',function(e){  
            $('#viewport').height('auto');  
        }); 

 

还有其他的一些移动端拉起键盘相关的问题,及解决方案:

  1. 有时候输入框 focus 以后,会出现软键盘遮挡输入框的情况,这时候可以尝试 input 元素的 scrollIntoView 进行修复。
  2. 在 iOS 下使用第三方输入法时,输入法在唤起经常会盖住输入框,只有在输入了一条文字后,输入框才会浮出。
  3. 有些第三方浏览器底部的工具栏是浮在页面之上的,因此底部 fixed 定位会被工具栏遮挡。解决办法也比较简单粗暴——适配不同的浏览器,调整 fixed 元素距离底部的距离。
  4. 最好将 header 和 footer 元素的 touchmove 事件禁止,以防止滚动在上面触发了部分浏览器全屏模式切换,而导致顶部地址栏和底部工具栏遮挡住 header 和 footer 元素。
  5. 在页面滚动到上下边缘的时候,如果继续拖拽会将整个 View 一起拖拽走,导致页面的“露底”。

参考:http://efe.baidu.com/blog/mobile-fixed-layout/

posted on 2016-04-13 14:37  清姿  阅读(9130)  评论(1编辑  收藏  举报