ChatGPT解决这个技术问题 Extra ChatGPT

位置:固定在 iPad 和 iPhone 上不起作用

一段时间以来,我一直在为 iPad 中的固定定位而苦苦挣扎。我知道 iScroll,但它似乎并不总是有效(即使在他们的演示中)。我也知道 Sencha 对此有修复,但我无法 Ctrl + F 获得该修复的源代码。

我希望有人可能有解决方案。问题是当用户在 iOS 驱动的移动 Safari 上向下/向上平移时,固定定位的元素不会得到更新。

看起来 jQuery Mobile 1.1 解决了这个问题:jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
几个 SO 问题可能重复。有关详细信息,请参阅 gist.github.com/avesus/…

G
GNTC

许多移动浏览器故意不支持 position:fixed;,理由是固定元素可能会妨碍小屏幕。

Quirksmode.org 网站有一篇很好的博文解释了这个问题:http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

另请参阅此页面以获取显示哪些移动浏览器支持 position:fixed; 的兼容性图表:http://www.quirksmode.org/m/css.html

(但请注意,移动浏览器的世界发展非常迅速,所以像这样的表格可能不会长时间保持最新状态!)

更新:据报道,iOS 5 和 Android 4 现在都具有 position:fixed 支持。

我今天在 Apple Store 中自己测试了 iOS 5,可以确认它确实可以在位置固定的情况下工作。但是,放大和平移固定元素存在问题。

我发现这个兼容性表比 quirksmode 表更新和有用:http://caniuse.com/#search=fixed

它有关于 Android、Opera(迷你和移动)和 iOS 的最新信息。


position:device-fixed 有点多余。 position:fixed 应该只符合 W3C 规范。
@TalviWatia - device-fixed 解决方案不是我回答的一部分。它可能有也可能没有建议,但链接的原因是对问题的解释,而不是他建议的解决方案。无论如何,自从发布此答案(正如我所说的那样)以来,事情已经发生了很大变化,并且许多较新的设备确实支持 fixed。不过,您仍然需要处理不需要的旧设备。
所以我很好奇,你手头的问题的解决方案到底是什么?您提供的链接虽然可能有帮助,但并不能解决手头的问题。不要厌倦,但人们倾向于支持在 SO 上实际上不是答案的答案。
@TalviWatia:在我写答案的时候,这个问题并没有很好的解决方案。我提供的链接是我所知道的最好的讨论,可以解释为什么事情会这样,在没有解决方案的情况下,这是我能提供的最好的。中间的时间发生了变化,所以链接里的讨论已经没有意义了,现在也有解决办法,但当时就是这样。
实际上 position:fixed 适用于比例 1,但是当用户缩放 ipad 时,它将无法正常工作。位置:设备固定存在?? safari ios 的 CSS 属性是否有效?
J
Jonathan.

固定定位在 iOS 上不像在计算机上那样工作。

想象一下,您在放大镜(视口)下有一张纸(网页),如果您移动放大镜和眼睛,您会看到页面的不同部分。这就是 iOS 的工作原理。

现在有一张透明塑料片,上面有一个字,这张塑料片无论如何都保持静止(位置:固定元素)。因此,当您移动放大镜时,固定元素似乎在移动。

或者,您不移动放大镜,而是移动纸张(网页),保持塑料片和放大镜不动。在这种情况下,塑料片上的单词会看起来保持不动,而其余的内容看起来会移动(因为它实际上是)这是一个传统的桌面浏览器。

所以在 iOS 中,视口在移动,在传统浏览器中,网页在移动。在这两种情况下,固定元素都保持在现实中;尽管在 iOS 上,固定元素似乎在移动。

解决此问题的方法是遵循 this article 中的最后几段

(基本上完全禁用滚动,将内容放在单独的可滚动 div 中(参见链接文章顶部的蓝色框),并且固定元素绝对定位)

"position:fixed" 现在可以像您在 iOS5 中所期望的那样工作。


当您在 IOS 上放大时,position:fixed 会发生一些奇怪的事情。请参阅stackoverflow.com/questions/52085998/…
J
Jason D.

position: fixed 在 android/iphone 上可以进行垂直滚动。但是您需要确保您的元标记已完全设置。例如

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">

此外,如果您计划在 4.0 之前的 android 上使用相同的页面,您还需要设置顶部位置,否则由于某种原因会添加一个小边距。


这实际上对我有用。之前,位置:固定在隐藏的输入元素上(请参阅纯 css 屏幕导航)导致浏览器在 iphone ios 8.3 上崩溃,但在平板电脑上没有。之后它工作正常。
不适用于 iPad iOS 10.3,在方形支架中水平放置。授权作者说这种方法适用于“电话”。
使用 user-scalable=0, minimum-scale=1.0, maximum-scale=1.0 禁止用户缩放会使许多用户无法访问该页面。在您的答案中添加有关它的警告会很有用
谢谢,在 iPad Pro 12.9 上为我工作
k
kenecaswell

我在 Safari (iOS 10.3.3) 上遇到了这个问题 - 浏览器在触发 touchend 事件之前不会重绘。固定元素未出现或被截断。

对我来说,诀窍是添加 transform: translate3d(0,0,0);到我的固定位置元素。

.fixed-position-on-mobile {
  position: fixed;
  transform: translate3d(0,0,0);
}

编辑 - 我现在知道转换解决问题的原因:硬件加速。添加 3D 转换会触发 GPU 加速,从而实现平滑过渡。有关硬件加速检查的更多信息,请查看本文:http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css


这实际上解决了我的滚动问题,它在使用 fixed 时在 iOS 设备上弹跳,添加了 transform 并已修复。
U
Uğur Özpınar

现在苹果支持

overflow:hidden;
-webkit-overflow-scrolling:touch;

这正是我在 iPad 上解决 background-size: coverfixed 问题所追求的
这适用于 iOS 7 中的 Mobile Safari。注意:它不适用于尚未升级到此版本的用户。
那么一定还有其他一些变量在起作用。我已经在 iOS 6 上进行了测试,但它无法正常工作,然后在 iOS 7 上进行了测试。
@NeilMonroe 嗯,也许。我确定我已经在没有问题的情况下在 iOS 6 上完成了它,但也许我使用了其他变量。不记得
这确实很有帮助,但似乎必须将 overflow 设置为 scroll
N
Nimantha

固定页脚(这里使用 jQuery):

if (navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod' || navigator.platform == 'Linux armv6l') 
{
    window.ontouchstart = function () 
    {
        $("#fixedDiv").css("display", "none");
    }

    window.onscroll = function() 
    { 
        var iPadPosition = window.innerHeight + window.pageYOffset-45; // 45 is the height of the Footer
         $("#fixedDiv").css("position", "absolute");
         $("#fixedDiv").css("top", iPadPosition);
         $("#fixedDiv").css("display", "block");
    }
}

// in the CSS file should stand:
#fixedDiv {position: fixed; bottom: 0; height: 45px;  whatever else}

B
Becario Senior

避免在同一个盒子上使用 transform:--- 和 position:fixed。如果有任何变换,元素将保持在 position:static 中。


T
Tower

我最终使用了新的 jQuery Mobile v1.1:http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

我们现在有一个可靠的重写,它在许多流行平台上提供真正的固定工具栏,并安全地回退到其他浏览器中的静态工具栏定位。这种方法最酷的部分是,与基于 JS 的解决方案在所有平台上强加不自然的滚动物理特性不同,我们的滚动感觉是 100% 原生的,因为它是。这意味着滚动感觉无处不在,并且适用于触摸、鼠标滚轮和键盘用户输入。作为奖励,我们基于 CSS 的解决方案是超轻量级的,不会影响兼容性或可访问性。


this method 也很优雅(但绝对是一种解决方法),它允许在 iOS 上固定对象而不使用 jQuery 或 JavaScript(仅使用 CSS)。它非常普遍适用。如果您希望“浮动”position:fixed 元素出现在滚动页面的前面,您只需要给它一个更高的 z-index 值,以便它保持在前面。
这绝对不能回答问题。
N
Nimantha

解决此问题的简单方法只是为您的元素键入转换属性。它将被修复。 .classname{ 位置:固定;变换:translate3d(0,0,0); }

你也可以试试他的方法,这也很好。

.classname{
      position: -webkit-sticky;
    }

a
abdullah

使用 jquery 我能够想出这个。它不平滑滚动,但它的伎俩。您可以向下滚动,固定的 div 会在顶部弹出。

CSS

<style type="text/css">
    .btn_cardDetailsPg {height:5px !important;margin-top:-20px;}
    html, body {overflow-x:hidden;overflow-y:auto;}
    #lockDiv {
  background-color: #fff;
  color: #000;
  float:left;
  -moz-box-shadow: 0px 4px 2px 2px #ccc;-webkit-box-shadow: 0px 4px 2px 2px #ccc;box-shadow:0px 4px 2px 2px #ccc;
  }
#lockDiv.stick {
  position: fixed;
  top: 0;
  z-index: 10000;
  margin-left:0px;
  }
</style>

HTML

<div id="lockSticky"></div>
<div id="lockDiv">fooo</div>

查询

<script type="text/javascript">
    function sticky_relocate() {
        var window_top = $(window).scrollTop();
        var div_top = $('#lockSticky').offset().top;
        if (window_top > div_top)
            $('#lockDiv').addClass('stick')
        else
            $('#lockDiv').removeClass('stick');
    }
    $(function() {
        $(window).scroll(sticky_relocate);
        sticky_relocate();
    });
</script>

最后我们要确定ipod touch在横向还是纵向模式下会相应显示

<script type="text/javascript">
    if (navigator.userAgent.match(/like Mac OS X/i)) {
        window.onscroll = function() {

        if (window.innerWidth > window.innerHeight) {
            //alert("landscape [ ]");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 268) + 'px';
        }

        if (window.innerHeight > window.innerWidth) {
            //alert("portrait ||");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 418) + 'px';
        }
        };
    }
</script>

T
Talvi Watia

尽管 CSS 属性 {position:fixed;} 似乎(大部分)适用于较新的 iOS 设备,但有时可能会出现设备怪癖并回退到 {position:relative;},而没有任何原因或原因。通常清除缓存会有所帮助,直到发生某些事情并且怪癖再次发生。

具体来说,来自 Apple 本身 Preparing Your Web Content for iPad

iPad 上的 Safari 和 iPhone 上的 Safari 没有可调整大小的窗口。在 iPhone 和 iPad 上的 Safari 中,窗口大小设置为屏幕大小(减去 Safari 用户界面控件),用户无法更改。要在网页中移动,用户可以通过双击或捏合来放大或缩小,或者通过触摸和拖动来平移页面来更改视口的缩放级别和位置。当用户更改视口的缩放级别和位置时,他们是在固定大小的可视内容区域(即窗口)内进行的。这意味着其位置“固定”到视口的网页元素最终可能会出现在可视内容区域之外,即屏幕外。

具有讽刺意味的是,Android 设备似乎没有这个问题。此外,在引用 body 标记时完全可以使用 {position:absolute;} 并且没有任何问题。

我找到了这个怪癖的根本原因;与 HTML 或 BODY 标记结合使用时,滚动事件效果不佳。有时它不喜欢触发事件,或者您必须等到滚动摆动事件完成才能接收事件。具体来说,视口在此事件结束时重新绘制,并且固定元素可以重新定位在视口中的其他位置。

所以这就是我要做的:(避免使用视口,并坚持使用 DOM!)

<html>
  <style>
    .fixed{
      position:fixed;
      /*you can set your other static attributes here too*/
      /*like height and width, margin, etc.*/
      }
    .scrollableDiv{
      position:relative;
      overflow-y:scroll;
      /*all children will scroll within this like the body normally would.*/
      } 
    .viewportSizedBody{
      position:relative;
      overflow:hidden;
      /*this will prevent the body page itself from scrolling.*/
      } 
  </style>
  <body class="viewportSizedBody">
    <div id="myFixedContainer" class="fixed">
       This part is fixed.
    </div>
    <div id="myScrollableBody" class="scrollableDiv">
       This part is scrollable.
    </div>
  </body>
  <script type="text/javascript" src="{your path to jquery}/jquery-1.7.2.min.js"></script>
  <script>
    var theViewportHeight=$(window).height();
    $('.viewportSizedBody').css('height',theViewportHeight);
    $('#myScrollableBody').css('height',theViewportHeight);
  </script>
</html>

本质上,这将导致 BODY 成为视口的大小并且不可滚动。嵌套在里面的可滚动 DIV 将像 BODY 一样滚动(减去摇摆效果,所以滚动确实在 touchend 时停止。)固定 DIV 保持固定而不受干扰。

附带说明一下,固定 DIV 上的高 z-index 值对于保持可滚动 DIV 显示在其后面很重要。我通常会添加窗口调整大小和滚动事件,以实现跨浏览器和备用屏幕分辨率的兼容性。

如果所有其他方法都失败了,上面的代码也适用于设置为 {position:absolute;} 的固定和可滚动 DIV。


p
phil294

这可能不适用于所有场景,但我发现 position: sticky(与 position: fixed 相同)仅在滚动容器不是主体,而是在其他东西内部时适用于旧 iPhone .

示例伪 html:

body                         <- scrollbar
   relative div
       sticky div

粘性 div 将在桌面浏览器上具有粘性,但在某些设备上测试过:Chromium:开发工具:设备仿真:iPhone 6/7/8,而使用 Android 4 Firefox,则不会。

然而,什么会起作用的是

body
    div overflow=auto       <- scrollbar
        relative div
            sticky div

n
nnimis

就我而言,这是因为使用动画显示了固定元素。如in this link所述:

在 Safari 9.1 中,在动画元素中包含 position:fixed-element 可能会导致 position:fixed-element 不出现。


m
mpalencia

在 Iphone X 上遇到了同样的问题。要修复它,我只需向容器添加高度

top: 0;
height: 200px;
position: fixed;

我刚刚添加了 top:0 因为我需要我的 div 保持在顶部


v
vr_driver

这似乎适用于 iOS 12.4.2 上的 iphone 6 Plus 上的 Ionic5

.large_player {
    float: left;
      bottom: 0;
      width: 100%;
      position: fixed;
      background-color: white;
      border-top: black 1px solid;    
      height: 14rem;
      z-index: 100;
      transform: translate3d(0,0,0);
  }

transform 标记使其工作,但滚动的工作方式似乎有点笨拙,它似乎在所有移动和重置后重新绘制“顶部”元素并使其有点跳跃。

或者,您也可以使用此标签选项,position: -webkit-sticky;,但是您将无法获得,或者可能在 WPA/浏览器或 Android 构建时遇到问题,同时必须进行版本检查并具有多个 CSS 标签。

.large_player {
    float: left;
      bottom: 0;
      width: 100%;
      position: -webkit-sticky;
      background-color: white;
      border-top: black 1px solid;    
      height: 14rem;
      z-index: 100; 
  }

我不知道它是在什么时候修复的,但后来的 iOS 手机可以在没有转换标签的情况下工作。不知道是iOS版还是手机版。

由于大多数 iOS 设备通常都使用最新的 iOS 版本,因此使用奇怪的解决方法是相当安全的 - 例如使用 transform 标记,而不是为了不到 1% 的用户而构建一个古怪的检测例程用户。

更新:

在进一步考虑了这个答案之后,这只是 ionic5+ 平台的另一种方式:

.TS

import {Platform } from '@ionic/angular';

constructor(
public platform: Platform 
) 
{  
    // This next bit is so that the CSS is shown correctly for each platform    

    platform.ready().then(() => {
    if (this.platform.is('android')) {
        console.log("running on Android device!");
        this.css_iOS = false;
    }
    if (this.platform.is('ios')) {
        console.log("running on iOS device!");
        this.css_iOS = true;
    }     
    if (this.platform.is('ipad')) {
        console.log("running on iOS device!");
        this.css_iOS = true;
    }
    });
}
css_iOS: boolean = false;

.HTML

<style *ngIf="css_iOS">
    .small_player {
      position: -webkit-sticky !important;
    }
    .large_player {
      position: -webkit-sticky !important;
    }
    </style>
    
    
    <style>
    .small_player {
    float: left;
      bottom: 0;
      width: 100%;
      position: fixed;
      background-color: white;
      border-top: black 1px solid;    
      height: 4rem;
      z-index: 100;
      /*transform: translate3d(0,0,0);*/
    }
    
    .large_player {
    float: left;
      bottom: 0;
      width: 100%;
      position: fixed;
      background-color: white;
      border-top: black 1px solid;    
      height: 14rem;
      z-index: 100;
      /*transform: translate3d(0,0,0);*/
    }
    </style>