I have a problem with scroll to element on mobile Safari in iframe (it works on other browsers, including Safari on mac).
I use scrollIntoView
. I want to scroll when all content has been rendered. Here is my code:
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); }
Advertisement
Answer
ScrollIntoView does not work (currently). But you can manually calculate the position of the element and scroll to it. Here is my solution
const element = document.getElementById('myId')
Pass the element to this function
/** 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' }) }
Pitfalls: Smooth scroll also does not work for ios mobile, but you can complement this code with this polyfill