AMP页面滚动时Header样式切换及offsetTop获取问题求助
Hey there! Let’s work through your Google AMP issues step by step—these are all typical hurdles with AMP’s component-based, sandboxed environment, so let’s get them sorted.
AMP restricts direct DOM manipulation via custom JavaScript, so you can’t tweak styles with vanilla scroll event listeners like you would in regular web dev. Instead, lean into AMP’s purpose-built tools: amp-position-observer paired with amp-animation (you’re already on the right track here!). The key is setting up trigger events that cover both scroll directions.
undefined for offsetTop AMP’s amp-script runs in a sandboxed iframe, which blocks full access to standard DOM properties like offsetTop because AMP handles layout calculations asynchronously. Instead, use AMP’s built-in AMP.getLayoutBox(element) method to fetch accurate position data. Here’s how to adjust your script:
// Inside your amp-script code const headerLogo = document.querySelector('.header__logo'); // Wait for AMP to finish rendering layout first AMP.ready().then(() => { const layoutData = AMP.getLayoutBox(headerLogo); console.log('Top offset:', layoutData.top); // This gives the correct position value });
Also, double-check your amp-script has the layout="container" attribute and that you’re not trying to access elements before they’re fully rendered.
Your current code uses two identical amp-position-observer elements, which creates conflicting triggers and misses upward scroll events. Instead, use a single observer to handle both directions by binding both enter and exit events to your animations.
First, add a small trigger anchor at the top of your page (this acts as the reference point for the observer):
<div class="scroll-trigger" style="height: 100px; width: 100%;"></div>
Then update your observer and animations to use this trigger, with events for both scroll directions:
<!-- Single observer for both scroll directions --> <amp-position-observer target=".scroll-trigger" intersection-ratios="0.7" on="enter:header-animation-back.start; exit:header-animation.start" layout="nodisplay" ></amp-position-observer> <!-- Animation for downward scroll --> <amp-animation id="header-animation" layout="nodisplay"> <script type="application/json"> { "selector": ".header__logo", "duration": "0.25s", "keyframes": {"transform": "translate(-50%, -50%)"}, "fill": "forwards" } </script> </amp-animation> <!-- Animation for upward scroll --> <amp-animation id="header-animation-back" layout="nodisplay"> <script type="application/json"> { "selector": ".header__logo", "duration": "0.25s", "keyframes": {"transform": "translate(-50%, 200%)"}, "fill": "forwards" } </script> </amp-animation>
Why this works:
- When scrolling down, the
.scroll-triggerexits the viewport (crosses the 0.7 intersection ratio), triggering your shrink/move animation. - When scrolling back up, the
.scroll-triggerre-enters the viewport, triggering the animation to revert the logo’s position.
For finer control (like triggering at a specific scroll depth), adjust the intersection-ratios value or add a threshold attribute to the observer.
内容的提问来源于stack exchange,提问作者Hovsep

