V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
weijar
V2EX  ›  Web Dev

谁能解释一下这段代码为什么在别的浏览器能工作但在 Safari 下不能工作吗?太离奇了

  •  2
     
  •   weijar · 185 天前 · 4632 次点击
    这是一个创建于 185 天前的主题,其中的信息可能已经有所发展或是发生改变。

    测试地址:

    https://www.oxyry.com/test/img.html

    点 Move 后,图片在动画移动中消失了!动画完成后才出来。

    这个在别的浏览器没问题,在我的 iPhone 13 Safari 中图片会消失。

    虽然 Safari 成吨的 Bug,但这个奇怪在于大部分移动图片操作不消失,但移动到有些位置会消失,想不通为什么。

    我的 App 中很多这类移动,最近有点崩溃因为想不到绕过这个 Bug 的方法,你们碰到过吗怎么解决的?

    文件源码:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    
    <style>
      body { margin: 0; }
      a[href], button { padding: 0.5em; font-size: xx-large; }
      #root { width: 320px; height: 300px; overflow: hidden; }
      #pic {
        transform: translateX(-1000px) scale(2.5);
        transform-origin: left top;
      }
    </style>
    
    <button id=btnMove>Move</button>
    
    <div id="root">
      <img id=pic src="https://s3.ifanr.com/wp-content/uploads/2022/01/ms_070621_item1_AI_BehavioralHealth.jpg">
    </div>
    
    <script>
    btnMove.onclick = () => {
      pic.style.transition = 'transform 1000ms'
      pic.style.transform = `translateX(-1100px) scale(2.5)`
    }
    </script>
    
    第 1 条附言  ·  185 天前
    说一下我为什么要这么移动图片:
    我在做一个图片查看器,在手指滑过图片后抬起时,图片要有一个动画滑行一段时间,这个代码就是干这个的。
    但我发现很多时候滑行中的图片消失了,这和图片的大小和格式没有关系。
    26 条回复    2022-03-05 17:57:32 +08:00
    BigDogWang
        1
    BigDogWang  
       185 天前
    Safari 15.3 测试正常
    BigDogWang
        2
    BigDogWang  
       185 天前
    手机上确实有问题
    Mutoo
        3
    Mutoo  
       185 天前   ❤️ 2
    没有细纠,应该是插值的 BUG 。
    如果项目中这类移动多的话,可以考虑使用 matrix

    transform: translateX(-1000px) scale(2.5)
    等价于
    transform: matrix(2.5, 0, 0, 2.5, -1000, 0)

    亲测,这方法在 iOS 可行。

    ref: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix()
    Biwood
        4
    Biwood  
       185 天前 via iPhone
    iOS 上的 CSS 动画是有点与众不同,我在 iPhone 测试了一下,Chrome 和 Safari 都没有动画,图片直接消失然后重现。猜测是不是应该把 transition 属性放到 css 里面提前设置。
    weijar
        5
    weijar  
    OP
       185 天前
    @Mutoo 非常感谢!测试下改成 matrix 真的没问题了
    weijar
        6
    weijar  
    OP
       185 天前
    @Biwood iPhone 上任何浏览器都是强制和 safari 共用同一内核,所以还是 safari 的问题。我没在 android 上试过,别的浏览器内核应该是没有这类问题的,这个写法应该是没问题的。
    learningman
        7
    learningman  
       185 天前
    @Biwood #4 iOS 上的 Chrome 叫 CriOS ,内核并不是 chromium ,只是接入了谷歌的生态
    maplerecall
        8
    maplerecall  
       185 天前 via Android
    也可以试着添加 translateZ(0)或者 will-change

    Safari 尤其是移动端的的渲染问题非常多,overflow 加 transform 更是重灾区,现在代码里很多 hack 都是为 Safari 写的,不愧为当代 IE
    weijar
        9
    weijar  
    OP
       185 天前
    @maplerecall 的确 bug 很多。之前在圆角框里的元素 transform 动画直接把圆角破坏了,要加 will-change 才能护住圆角。但在这里之前试过似乎 will-change 没用。
    EIJAM
        10
    EIJAM  
       185 天前 via iPhone
    不兼容很正常吧。谷歌为了推自家 Chrome ,还时不时地给 Firefox 下个绊子,定制一个 Firefox 专属 bug 。
    EIJAM
        11
    EIJAM  
       185 天前 via iPhone
    maplerecall
        12
    maplerecall  
       185 天前 via Android
    @EIJAM 这可不是不兼容或者被下拌子,而是对标准实现有问题,简单的说就是 bug ,和 Chrome 与 Firefox 没有任何关系。
    Mutoo
        13
    Mutoo  
       185 天前   ❤️ 2
    @Mutoo 稍微测试了一下,不是插值的问题。我试了一些边界条件,发现是 Safari iOS 做了不恰当的优化。假定 scale 为 1 ,当图片的 translate 发生在屏幕外的时候,safari 不渲染这个 translation ,但它没考虑到 scale 的情况。

    测试了几个边界条件:
    translateX(-600px) scale(1) 到 translateX(-700px) scale(1) 有动画
    translateX(-600px) scale(2.5) 到 translateX(-700px) scale(2.5) 有动画
    translateX(-700px) scale(1) 到 translateX(-800px) scale(1) 无动画
    translateX(-700px) scale(2.5) 到 translateX(-800px) scale(2.5) 无动画
    jinliming2
        14
    jinliming2  
       185 天前   ❤️ 2
    经过测试,应该确定确实是 iOS Safari 的 bug ,应该是 safari 在做优化的时候,只考虑了 translate 而忘记考虑 scale 的影响了,具体现象:
    你同时为图片增加了 translateX 和 scale ,图片原本宽度为 620px ,它发现你 translateX(-1000px) 之后,图片应该已经在可见范围之外了,并且动画运动到 translateX(-1100px) 全程都应该在可见范围之外,所以直接将动画“优化”掉不执行了,反正效果就是元素在原来的位置消失,在动画结束之后再在新位置显示出来,那就直接不计算动画了,直接“跳刀 blink”即可。
    但是它没料到实际上你同时为图片增加了 scale(2.5),把图片放大了,此时图片宽度变成了 1550px ,动画全程都在可见范围之内了,导致这个“优化”露馅了。

    按照这个理论,你将动画改为从 translateX(620px) 变化到 translateX(621px) 就会触发 bug ,但是只要某一个值小于 620px (图片原始宽度),bug 就不会复现。

    @Mutoo #3 给出的用 matrix 的解决方案,应该是绕过了这个 bug ,将 translateX 和 scale 的结果融合进同一个矩阵,Safari 就会考虑完整的变换结果之后再进行动画的优化。

    应该可以给 webkit 提 issue 了。
    EIJAM
        15
    EIJAM  
       185 天前 via iPhone
    @maplerecall 引用:“它们最近在 YouTube 视频网站上添加了一个隐藏的空 div 参数,导致我们无法启用 fast-path 硬件加速”
    weijar
        16
    weijar  
    OP
       185 天前
    @Mutoo @jinliming2 感谢二位让我过个好年

    我之前是一点都没想到原因。特别是我的图片查看器在手指拖来拖去时图片很跟手不会消失,手指一松图片就不见,简直见鬼,因为拖动时虽也是一样的 translate 参数但没用 transition 所以就不触发 bug
    makelove
        18
    makelove  
       185 天前   ❤️ 3
    @EIJAM 不要像个精神股东一样强行洗地,这不是一回事。开放 Web 不符合苹果利益对自家内核不上心甚至不让别人用自研内核符合自私的人性,这是垄断之恶
    EIJAM
        19
    EIJAM  
       185 天前 via iPhone
    @makelove 不是精神股东啊,就是股东,这两年还赚了不少呢。谷歌的股票也买了点,但我讨厌的浏览器还是 chrome ,以开放之名行垄断之实。
    rabbbit
        20
    rabbbit  
       185 天前
    这种 bug 挺多的, 例如有时候给 safari 添加了 overflow-scrolling 之后有些子元素直接没了.简直无语.
    maplerecall
        21
    maplerecall  
       185 天前 via Android   ❤️ 7
    @EIJAM 这个帖子的讨论点是 Safari 的 bug ,并且这个 bug 所涉及到的方面还是很基础的规范,而不是什么被 Chrome 推成事实标准的特殊功能(事实上现有 Web 的不少东西反而是被苹果 webkit 搞成事实标准,导致其他内核不得不适配)

    所以我不是很理解你贴一个和主题完全不相关的 Google 罪证是什么意思。类比就是我们讨论 go 的问题,你突然冒出一个 java 罪大恶极,这不就直接引战了嘛(然后我就上钩了🐶)
    nbndco
        22
    nbndco  
       185 天前   ❤️ 2
    @EIJAM 怎么还在传这个烂梗。别的不说,这个实习生自己跑出来说叠一层空白 div 就会让硬件加速失效(并且微软之后立刻就修复了,可见只是自己的代码写的烂)也不知道是丢谁的人。

    至于这个空白 div 的背后逻辑,我看这篇文章解释的应该差不多。https://medium.com/@jeremy.noring/did-google-cripple-edges-youtube-performance-ce5169d3e5f4

    致于 Google 为何不会做这种事,我这么说吧,公司文化先不谈,Google 内部连 Windows 都基本找不着,谁去找 IE 的 bug 来减速 YouTube 。Google 也真没这么牛去找到这些 bug 。
    Goooooos
        23
    Goooooos  
       185 天前 via Android   ❤️ 2
    @maplerecall #21 这叫围魏救赵
    magicdawn
        24
    magicdawn  
       184 天前 via Android
    前端都知道,safari 新时代的 IE
    dany813
        25
    dany813  
       182 天前
    safari 上面的问题确实不少,几年前改过很多
    sunwang
        26
    sunwang  
       156 天前
    感谢各位🙏,今天碰到和楼主同样的问题,已经解决啦
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3888 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 01:24 · PVG 09:24 · LAX 18:24 · JFK 21:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.