position:fixed之safari的坑

mobile开发如今已经越来越步入正规,很多问题也得到了各大浏览器厂商的支持和修正,比如今天要说的ipone下的fixed,如今Safari也的得到了支持,不过却还有些比较坑得地方。

今天要说得这个坑是关于safari全屏模式,当页面进入全屏模式(向下滚动以后页面默认会进入全屏模式)时页面底部就不可交互,看起来好像事件失效了一样,这个是时候窗口底部的任何工具栏,链接或者通过fixed底部固定的工具栏等等都没法点击了,这时点击只会触发Safari退出全屏得动作,然后调出Safari 工具栏,需要再次点击这些交互项才能触发动作,比如按钮或链接等等都需要两次点击才触发,这个行为就想页面底部有个透明遮罩一样,这段话可能有点绕,大家可以看下下面得test case:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<div style="height: 4600px;background: #ccc"></div>
<div class="test" style="height: 300px;background: sandybrown;width: 100%;position: fixed;bottom: 0;left: 0;font-size:16pt">
  <div style="height: 100px; background: cadetblue;position: absolute;top:0;width:100%">
      我没给safari挡住,任何时候都可以正常触发;
    </div>
    <p style="position: absolute; top: 120px;">如果是全屏,我可能给safari挡住了,事件不会触发;</p>

</div>
<script>
  var Box = document.getElementsByClassName("test")[0];
  Box.addEventListener("touchend", function(){
    alert("click");
  })
</script>
</body>
</html><!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<div style="height: 4600px;background: #ccc"></div>
<div class="test" style="height: 300px;background: sandybrown;width: 100%;position: fixed;bottom: 0;left: 0;font-size:16pt">
<div style="height: 100px; background: cadetblue;position: absolute;top:0;width:100%">
      我没给safari挡住,任何时候都可以正常触发;
    </div>
    <p style="position: absolute; top: 120px;">如果是全屏,我可能给safari挡住了,事件不会触发;</p>

</div>
<script>
  var Box = document.getElementsByClassName("test")[0];
  Box.addEventListener("touchend", function(){
    alert("click");
  })
</script>
</body>
</html>

在上面的case很明显,在全屏模式得时候,当底部的fixed元素足够高的时候多余得部分的touch等等事件都是还能触发得,所以初步可以得出此问题,是safari在全屏模式时会在底部creat一个透明的遮罩去用于它退出全屏模式,这个遮罩得zIndex优先级是远远高于整个页面上dom tree得任何节点。

其实在实际开发中,底部可能有的都是些链接或者其他得touchend事件之类的,所以这个问题也仅仅只会让人觉得交互差,不会产生实际问题,但是向我最近做的底部的fixed工具条内容却是比较多需要做move操作,全屏模式下时,touchmove却是不会触发遮罩事件退出全屏模式,这时看起来好像事件失效了一样,就比较坑了,目前能解决的方法也只能通过设备和浏览器判断,让它fixed到顶部去避免此问题。

PS:另外之前在做设备放缩功能的时候三星android(具体机器型号记不住了)下,也会create类似的遮罩而导致缩放失效

### 使用 `position: fixed` 和 `left: 80px` 实现布局 当使用 `position: fixed` 并设置 `left: 80px` 时,元素会固定在距离浏览器窗口左侧边缘80像素的位置[^1]。这种定位方式使得元素不会随着页面滚动而移动。 #### HTML 结构示例 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Fixed Position Example</title> <style> body { margin: 0; padding: 0; } .fixed-box { width: 200px; height: 200px; background-color: red; border: 2px solid yellow; position: fixed; left: 80px; top: 50%; transform: translateY(-50%); } </style> </head> <body> <div class="fixed-box"></div> </body> </html> ``` 在这个例子中,`.fixed-box` 类定义了一个宽度为200像素、高度也为200像素的红色方块,并设置了黄色边框。通过应用 `position: fixed` 及其对应的偏移量 (`left: 80px`) 来确保该盒子始终位于视窗左边距80像素处[^2]。为了使此元素垂直方向上也处于中心位置,可以采用 `top: 50%` 加上 `transform: translateY(-50%)` 的方法来调整顶部间距并向上平移一半的高度[^3]。 #### 解决常见问题方案 有时可能会遇到 `position: fixed` 不起作用的情况。这通常是因为存在某些特定条件影响了它的行为: - **父级容器的影响**:如果某个祖先元素指定了 `transform`, `perspective`, 或者 `filter` 等属性,则这些特性会使后代中的所有 `position: fixed` 转变为相对该祖先行内流内的定位而非相对于整个文档根节点。 - **移动端设备上的表现差异**:部分旧版iOS Safari 浏览器可能无法正确处理 `position: fixed` ,尤其是在有溢出内容的情况下;此时可考虑使用 JavaScript 动态计算和更新元素坐标作为替代方案。 对于上述提到的第一种情形,在实际开发过程中应当尽量避免不必要的变换操作应用于包含需被固定的子组件之上;而对于第二种情况则建议测试不同平台下的兼容性和性能表现,必要时采取相应的优化措施或寻找其他可行的技术路线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值