ios 移动的Safari,scrollIntoView不工作

u4dcyp6a  于 2023-07-01  发布在  iOS
关注(0)|答案(4)|浏览(302)

我在iframe中的移动的Safari上滚动到元素有问题(它在其他浏览器上工作,包括Mac上的Safari)。
我用scrollIntoView。我想在呈现所有内容后滚动。下面是我的代码:

var readyStateCheckInterval = setInterval(function () {
    if (document.readyState === "complete") {
       clearInterval(readyStateCheckInterval);
        $browser.notifyWhenNoOutstandingRequests(function () {
            if (cinemaName != null && eventId == null) {
                scrollToCinema();
            } else {
                scrollToEvent();
            }
        });
     }
}, 10);
    
    
function scrollToEvent() {
    var id = eventId;
    var delay = 100;
    
    if (cinemaName != null) {
        id = cinemaName + "#" + eventId;
    }
    
    if ($rootScope.eventId != null) {
        id = $rootScope.cinemaId + "#" + $rootScope.eventId;
    }
    
    $timeout(function () {
        var el = document.getElementById(id);
        if (el != null)
        el.scrollIntoView(true);    
        $rootScope.eventId = null;
    }, delay);
}
2sbarzqh

2sbarzqh1#

ScrollIntoView不工作(当前)。但是您可以手动计算元素的位置并滚动到它。这是我的解决方案

const element = document.getElementById('myId')

将元素传递给此函数

/** Scrolls the element into view
 * Manually created since Safari does not support the native one inside an iframe
*/
export const scrollElementIntoView = (element: HTMLElement, behavior?: 'smooth' | 'instant' | 'auto') => {

  let scrollTop = window.pageYOffset || element.scrollTop

   // Furthermore, if you have for example a header outside the iframe 
   // you need to factor in its dimensions when calculating the position to scroll to
   const headerOutsideIframe = window.parent.document.getElementsByClassName('myHeader')[0].clientHeight

  const finalOffset = element.getBoundingClientRect().top + scrollTop + headerOutsideIframe

  window.parent.scrollTo({
    top: finalOffset,
    behavior: behavior || 'auto'
  })
}

陷阱:平滑滚动也不适用于ios移动的,但您可以使用此polyfill补充此代码

eimct9ow

eimct9ow2#

根据我的经验,scrollIntoView()有时会在我的iPhone和iPad上失败,有时会工作(在我自己的网站上)。我不用iframe safari和firefox在上述设备上都是如此。
对我有效的解决方案是弹出你需要滚动到DIV eg内部的元素。作为该DIV中的第一个元素。嘿,Presto,然后工作正常!看起来像是苹果的一个狡猾的实现。

mi7gmzs6

mi7gmzs63#

你最有可能有完全相同的问题,我刚刚调试。Safari会自动调整框架的大小以适应其内容。因此,Iframe的父对象将在Safari中拥有滚动条。所以从Iframe内部调用scrollintoview本身就是“失败”的。
如果Iframe是跨域的,通过窗口访问父文档,父文档将被拒绝.
如果你需要一个跨域的解决方案检查我的答案here.
基本上,我使用post消息来告诉父页面在移动的Safari跨域时进行滚动。

omqzjyyz

omqzjyyz4#

scrollIntoView方法在iOS上的Safari中对我的工作不一致。当我点击一个输入元素进入焦点时,它会每隔一秒工作一次,否则它会在输入元素下面滚动。似乎问题出在弹出的iOS键盘上。我的解决方案是在scrollIntoView上设置一个计时器,在键盘出现后触发。

const inputRef = useRef(null);

const handleFocus = () => {
    setTimeout(() => {
        inputRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }, 100);
};

相关问题