如何在iOS(iPhone/iPad)上解决底部工具栏的position:fixed问题

19

我在网站底部使用position:fixed将一条工具栏固定在每个页面上。然而,在iPhone或iPad等设备上,这个属性并不起作用。

我试图使用JavaScript来检测屏幕高度和滚动位置,在iPad上效果很好:

$( window ).scroll( function ( ) { $( "#bar" ).css( "top", ( $( window ).height() + $( document ).scrollTop() - 90 ) +"px" );  } );

我正在使用jQuery。问题在于,由于窗口的高度不包括位置栏(以及调试栏(如果存在)),所以此代码在iPhone上不能正常工作,因此该栏在开始时会出现正确的位置,但是随着滚动会固定在正确位置上方(移动Safari位置栏使用的像素数量)。

有没有一种方法可以获取此信息并正确地修复此工具栏?

请注意,这不是为iPhone制作的网站,因此我无法完全使用iScroll等技巧。


2
+1 表示 iPad 兼容代码。我会在这里等待答案 :) - Dan Hanly
iOS 5似乎通过正确解释position:fixed元素解决了这些问题。 - Wes Souza
也许等它正式发布后我会看一下。 - Dan Hanly
9个回答

3

iOS 8.4及以上版本,可以使用position: sticky;或者position: -webkit-sticky;来解决这个问题。


5
Sticky position是指元素在滚动时保持静态位置,直到达到窗口顶部,然后固定在那里。而这个问题是要将一个元素固定在窗口底部。 - 2540625

1

我刚刚做了类似的事情,将导航固定在窗口顶部。 导航从标题下方开始,如果您滚动超过它,则会固定。 iOS5支持固定定位。 该项目将在滚动结束后自动定位,但仍然可以正常工作。 '#sticky-anchor'是我导航周围的包装器div。

不记得我从哪里找到所有这些东西了,从许多网站中获得了一些小片段。 您可以根据需要进行调整。

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

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

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

// sticky nav iPhone android mobile way
// iOS 4 and below

   if (navigator.userAgent.match(/OS 5(_\d)+ like Mac OS X/i)) {
        //do nothing uses sticky_relocate above
   } 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

3
有趣的是这两个链接告诉我放弃,我在想这是否有可能实现。 - Wes Souza
2
如果您找到了解决方案,请告诉我们,您可以在SO上回答自己的问题。 - Nick Weaver
1
这个网站的持续头部是我见过最少错误的。也许他们在做某些事情来解决这个问题? - sheriffderek

1

我在我的网站上修复了这个问题,并在Stack Overflow上回答了这个问题。从那以后,我收到了很多人的感谢,因为他们已经实现了它。抱歉我没有时间做一个总结。

https://dev59.com/2msz5IYBdhLWcg3wiYY0#10030251


0

尝试根据window.innerHeight在iPhone上隐藏/显示底部固定导航。每当工具栏显示时,通常是向上滚动时,您可以显示底部导航,并在滚动到工具栏隐藏时将其隐藏。

您可以使用类似以下代码的代码:

    var windowHeight = {
  small: window.innerHeight,
  middle: window.innerHeight,
  big: window.innerHeight
}
window.addEventListener('resize', function(){
  var currentHeight = window.innerHeight;
  if (currentHeight < windowHeight.small) {
    windowHeight.small = currentHeight;
  }

  if (currentHeight > windowHeight.big) {
    windowHeight.big = currentHeight;
  }

  console.log('windowHeight.small', windowHeight.small, 'windowHeight.middle', windowHeight.middle, 'windowHeight.big', windowHeight.big, 'currentHeight', currentHeight);

  if (currentHeight === windowHeight.big) {
    transform(stickyNav, 'translate3d(0,120%,0)');
    console.log('Hide bottom nav on big screen!');
  } else if (currentHeight === windowHeight.middle) {
    transform(stickyNav, 'translate3d(0,0,0)');
    console.log('Show bottom nav on middle screen!');
  } else {
    transform(stickyNav, 'translate3d(0,-100%,0)');
    console.log('Display bottom nav high up on smaller screen!');
  }
})

transform(stickyNav, 'translate3d(x,x,x)')函数是一个简单的函数,它接收底部导航并应用转换以隐藏/显示底部放置的项目。


0

iScroll 可能是您问题的最简单解决方案。与您的想法相反,它也适用于 Android 和 Opera。新版本表现出色。

http://cubiq.org/iscroll-4


0

我记得使用 position: sticky; bottom: 0; 来解决这个问题,用零高度的容器元素来实现,在实际想要固定到视口底部的元素上,使用 position: absolute; bottom: var(--how-much-space-u-like-below-bottom-of-screen-and-fixed-element);。我相信它至少在iOS Safari 15和16上解决了这个问题。

<div class="sticky-container" style="position: sticky; bottom: 0;">
  <div class="fixed-to-bottom" style="position: absolute; bottom: 1rem;">
    <button>hello world</button>
  </div>
</div>

0
这段 jQuery 代码对我很有用:
if(navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod'){
    $("#footer_menu").css("position", "fixed").css("top", $('window').height());
};

否则 #footer_menu 的 CSS 样式为:

position:fixed;
bottom:0;
width:100%;
padding:5px 0;
text-align:center;
height:44px;

我认为设置高度有助于正确渲染,在桌面浏览器上,我希望将此菜单固定在浏览器窗口底部。


-3

正如我一开始所提到的:“请记住,这不是为iPhone制作的网站,因此我无法使用iScroll等技巧。” 这就是那个技巧。 - Wes Souza
1
Google的代码是一个很好的起点。然而,我认为它有漏洞(我认为读取this.element = this;的那一行应该是this.element = element;),而且它不完整(几个关键函数留给读者作为“练习”)。确切地获取动量、反弹等细节非常重要,但这些都被省略了。我很想看到缺失方法的实现! - mattstuehler
3
此回答中提供的链接已失效。 - EleventyOne

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