【问题标题】:How to position a fixed-location element on IOS browser when zoomed?缩放时如何在IOS浏览器上定位固定位置的元素?
【发布时间】:2019-02-04 17:56:38
【问题描述】:

我有一个不错的小React drag-drop 库,适用于鼠标和触摸系统。对于触摸,它通过clientXclientY (e.targetTouches[0].clientX, e.targetTouches[0].clientY) 获取触摸位置。它使用这些坐标来放置具有position: fixed 的拖动元素。

然而事实证明,至少在 IOS Safari (v.11.x) 上,当您缩放显示时,position:fixed 的坐标系不再与窗口坐标系匹配。所以被拖拽的元素显示在页面的错误位置。

将放大的浏览器窗口想象成一个小矩形视图,放在一个包含未缩放内容的较大矩形上。 location:fixed 坐标系使用较大的矩形。窗口坐标系使用小坐标系。

当您滚动时,窗口会以难以描述的方式围绕较大的矩形平移,结果是位置固定区域中的 0,0 和浏览器窗口中的 0,0 之间的偏移量总是在变化。

如何获取浏览器窗口和“位置:固定”坐标系之间的偏移量? (然后我可以将该偏移量添加到拖动元素的位置以正确定位它。)

【问题讨论】:

    标签: javascript ios css iphone


    【解决方案1】:

    在 0,0 处粘贴一个元素,位置:固定。

    使用getBoundingClientRect() 获取浏览器窗口的 x/y 偏移量。

    然后删除元素。

    function getFixedOffset() {
        let fixedElem = document.createElement('div');
        fixedElem.style.cssText = 'position:fixed; top: 0; left: 0';
        document.body.appendChild(fixedElem);
        const rect = fixedElem.getBoundingClientRect();
        document.body.removeChild(fixedElem);
        return [rect.left, rect.top]
    }
    

    这可行(耶!)但感觉很笨拙,每次用户拖放时创建然后销毁一个 DOM 元素。欢迎提出其他建议。

    【讨论】:

    • 我尝试在具有溢出:滚动的容器内使用拖动项目,无论我使用位置:固定还是位置,它都会在放大和向下滚动时稍微偏离屏幕:absolute,因为更新的视口没有被考虑在内。我使用了基本相同的解决方法,一个名为 #overlay_touch 的 div 放置在底部,但设计为覆盖。这是适用于 iOS 14、iPhone 11 Pro Max 的 Safari。
    • window.visualViewport 至少会提供比例和左/上信息,当且仅当您将元视口标签添加到页面头部时,但我不确定需要的调整数学将需要应用于 getBoundingClientRect() 的结果。
    • getBoundingClientRect() 在 safari 中使用放大时会给出不正确的结果,因为 bug bugs.webkit.org/show_bug.cgi?id=77998。我在 IOS 中测试过,使用缩放时返回的最大值不正确。
    猜你喜欢
    • 2012-08-04
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多