diff --git a/src/service/viewport/viewport-impl.js b/src/service/viewport/viewport-impl.js index d1e5fd0a49f0..b2a1f20e3493 100644 --- a/src/service/viewport/viewport-impl.js +++ b/src/service/viewport/viewport-impl.js @@ -228,6 +228,11 @@ export class ViewportImpl { // the size has changed between `disconnect` and `connect`. this.resize_(); } + if (this.scrollTop_) { + // Remeasure scrollTop when resource becomes visible to fix #11983 + this./*OK*/ scrollTop_ = null; + this.getScrollTop(); + } } else { this.binding_.disconnect(); } diff --git a/test/unit/test-viewport.js b/test/unit/test-viewport.js index 5f4dc418118b..da56cdb72a11 100644 --- a/test/unit/test-viewport.js +++ b/test/unit/test-viewport.js @@ -395,6 +395,27 @@ describes.fakeWin('Viewport', {}, env => { expect(binding.disconnect).to.be.calledOnce; }); + it('should update scroll position when visibility changes', () => { + binding = new ViewportBindingDef(); + binding.getScrollTop = (() => { + const generator = (function*() { + yield 25; + return 100; + })(); + return () => generator.next().value; + })(); + viewport = new ViewportImpl(ampdoc, binding, viewer); + + // Force scrollTop to be measured + viewport.getScrollTop(); + expect(viewport./*OK*/ scrollTop_).to.equal(25); + // Toggle visibility state + changeVisibilityState('prerender'); + changeVisibilityState('visible'); + // Expect scrollTop to be remeasured + expect(viewport./*OK*/ scrollTop_).to.equal(100); + }); + it('should resize only after size has been initialed', () => { onVisibilityHandlers.length = 0; changeVisibilityState('visible');