移动 Safari,scrollIntoView 不起作用

Mobile Safari, scrollIntoView doesn't work

我在 iframe 的移动 Safari 上滚动到元素时遇到问题(它适用于其他浏览器,包括 mac 上的 Safari)。

我使用 scrollIntoView。我想在呈现所有 contnet 时滚动。这是我的代码:

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);
}

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

补充此代码

您遇到的问题很可能与我刚刚调试的问题完全相同。 Safari 会自动调整框架大小以适合其内容。因此,Iframe 的父级将在 Safari 中具有滚动条。所以从 Iframe 本身内部调用 scrollintoview 'fails'.

如果 Iframe 跨域通过 window.parent.document 访问父文档将被拒绝。

如果您需要跨域解决方案,请查看我的答案

基本上,当在 Mobile Safari 跨域中时,我使用 post 消息告诉父页面自行滚动。

根据我的经验,scrollIntoView() 有时会在我的 iphone 和我的 ipad 上失败,有时它会起作用(在我自己的网站上)。我没有使用 iframe。上述设备上的 Safari 和 Firefox 都是如此。

对我有用的解决方案是将您需要滚动到的元素弹出 DIV 例如。作为 DIV 中的第一个元素。嘿,很快它就可以正常工作了! 看起来像是 Apple 的一个狡猾的实现。