Mobile Safari中的固定定位

67

在移动版Safari中,是否有可能相对于视口固定位置?正如许多人所指出的那样,position: fixed无法使用,但Gmail刚刚推出了一种几乎符合我的要求的解决方案-请参见邮件视图上的浮动菜单栏。

通过JavaScript获取实时滚动事件也是一个合理的解决方案。

11个回答

74

只需两行代码即可实现此固定位置的div,它会在滚动时将div移动到页面底部。

window.onscroll = function() {
  document.getElementById('fixedDiv').style.top =
     (window.pageYOffset + window.innerHeight - 25) + 'px';
};

8
这难道不会有点延迟吗? - changelog
25
onscroll事件直到滚动完成后才会触发,因此元素会随页面滚动而滚动,然后在滚动完成时自动贴在底部。 - grant
13
此外,移动版Safari现在支持硬件加速变换。所以,element.style.webkitTransform = "translate3d(0, " + window.pageYOffset + "px, 0)"; 的执行速度会比设置top值更快且更流畅。 - Adam
@Adam:不知道为什么,但这对我没有起作用。元素根本没有显示出来。之前它有 position:fixed;top:50%;left:50%; - testing

35

1
今天早上看到了。终于! - Sophie Alpert
1
其他不在iOS上的移动设备怎么办? - danwellman
20
为什么这是被接受的答案?因为仍然有许多用户使用较低版本的iOS,其中一个原因是由于他们设备的缺失支持。 - NickGreen
1
@NickGreen - 因为它适用于iOS 5,我们希望用户将旧设备丢弃,这是您在Apple上必须做的事情,因为大多数软件不支持旧手机。 - Neil
12
如果你在IOS 5.1.1(或更早的版本)上使用position:fixed,你可能会遇到很多问题。它有漏洞,非常多漏洞。 - Tim Haines
显示剩余2条评论

10

1
链接已过期。请尝试使用https://web.archive.org/web/20141001100814/https://developers.google.com/mobile/articles/webapp_fixed_ui。 - Suraj

6

它对我有效:

function changeFooterPosition() {   
  $('.footer-menu').css('top', window.innerHeight + window.scrollY - 44 + "px");
}

$(document).bind('scroll', function() {
  changeFooterPosition();
});

(44是我的进度条的高度)

尽管进度条只在滚动结束时移动...


5

深度链接:http://developer.apple.com/library/ios/#technotes/tn2010/tn2262/#//apple_ref/doc/uid/DTS40009577-CH1-DontLinkElementID_5 - ken
34
该链接中没有给出“非常好的理由”。所做的只是对当前情况的描述。 - Dominic Scheirlinck

4
我认为 Gmail 只是在计时器上跟踪滚动位置并相应地重新定位 div
我见过的最好的解决方案在 doctyper
一个更简单的 jQuery 解决方案,可以在滚动时移动一个元素:link

你怎么获取滚动位置呢? - Sophie Alpert
我已经添加了一个更简单的方法来跟踪onscroll。随意查找jQuery以找到要使用的确切方法;它可能是window.pageYOffset,但我不确定。 - rpetrich
1
Doctyper的问题在于当有太多内容需要滚动时,手机响应能力开始变慢... - gamma

3

我都用过。两者都很好。如果需要更多的滚动控制(例如固定定位),iScroll 4 更加全面。 Touch Scroll 功能较少且更为简洁。 - doublejosh

1
这是我的做法。 我有一个导航块,当你向下滚动页面时,它会“粘”在窗口顶部。 如果你向上滚动回到顶部,导航就回到原来的位置。 我在CSS中使用position:fixed来适用于非移动平台和iOS5。 其他移动版本在屏幕停止滚动之前会有一些“延迟”。
// css
#sticky.stick {
    width:100%;
    height:50px;
    position: fixed;
    top: 0;
    z-index: 1;
}

// jquery 
//sticky nav
    function sticky_relocate() {
      var window_top = $(window).scrollTop();
      var div_top = $('#sticky-anchor').offset().top;

      if (window_top > div_top)
        $('#sticky').addClass('stick');
      else
        $('#sticky').removeClass('stick');
     }

$(window).scroll(function(event){

    // sticky nav css NON mobile way
       sticky_relocate();

       var st = $(this).scrollTop();

    // sticky nav iPhone android mobile way iOS<5

       if (navigator.userAgent.match(/OS 5(_\d)+ like Mac OS X/i)) {
            //do nothing uses sticky_relocate() css
       } else if ( navigator.userAgent.match(/(iPod|iPhone|iPad)/i) || navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) ) {

            var window_top = $(window).scrollTop();
            var div_top = $('#sticky-anchor').offset().top;

            if (window_top > div_top) {
                $('#sticky').css({'top' : st  , 'position' : 'absolute' });
            } else {
                $('#sticky').css({'top' : 'auto' });
            }
        };

1
<meta name="viewport" content="width=320, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/> 

同时,确保此元标记中不存在height=device-height有助于防止页面上本来不存在的额外页脚填充。菜单栏高度增加了视口高度,导致固定背景变得可滚动。

0
我们的Web应用程序需要一个固定的标题。 我们很幸运,因为我们只需要支持最新的浏览器,但Safari在这个领域的行为给我们带来了真正的问题。
正如其他人指出的那样,最好的解决方法是编写自己的滚动代码。 但是,我们无法为修复仅在iOS上发生的问题而证明这种努力是有道理的。 希望苹果公司能够解决这个问题更有意义,特别是因为QuirksMode建议,现在苹果公司在他们对“position:fixed”的解释上独树一帜。

http://www.quirksmode.org/blog/archives/2013/12/position_fixed_1.html

我们的解决方案是在用户缩放时在“position:fixed”和“position:absolute”之间切换。这将替换我们的“浮动”标题,使其具有可预测的行为,这对于可用性非常重要。当缩放时,行为不是我们想要的,但用户可以通过反向缩放轻松解决这个问题。
// On iOS, "position: fixed;" is not supported when zoomed, so toggle "position: absolute;".
header = document.createElement( "HEADER" );
document.body.appendChild( header );
if( navigator.userAgent.match( /iPad/i ) || navigator.userAgent.match( /iPhone/i )) {
    addEventListener( document.body, function( event ) {
        var zoomLevel = (( Math.abs( window.orientation ) === 90 ) ? screen.height : screen.width ) / window.innerWidth;
        header.style.position = ( zoomLevel > 1 ) ? "absolute" : "fixed";
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接