I am trying to use amp-script
to toggle a class on my nav
(top menubar) when the window starts to scroll. The effect is to turn the fixed nav from semi-transparent to solid white.
Here is what I tried ...
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<title>My AMP Page</title>
<link rel="canonical" href="self.html" />
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>
<style amp-custom>
nav {
position: fixed;
top: 0;
width: 100vw;
color: white;
background-color: rgba(0, 0, 0, 0.2);
z-index: 10;
text-align: center;
}
.opaque {
background-color: white;
color: black;
}
.hero {
height: max(25vh, 250px);
width: 100vw;
background: red;
}
.spacer {
height: 4em;
background: blue;
margin: 0.5em;
}
</style>
<meta name="amp-script-src" content="sha384-bpf6fazoofAb6S1aK0_hOIa1g6nDaC_SPbTuSJsMxEzAPc11oKjAnJZmeFAMKc2p ">
</head>
<body>
<script id="scroll-listener" type="text/plain" target="amp-script">
document.addEventListener("scroll", myFunction);
function myFunction() {
console.log('scrolled!!');
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
document.getElementById("topnav").className = "opaque";
} else {
document.getElementById("topnav").className = "";
}
}
</script>
<nav id="topnav">
<h1>ACME Inc.</h1>
</nav>
<main>
<header class="hero"></header>
<article>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
</article>
</main>
</body>
</html>
Unfortunately the script has no effect at all. I've also placed console.log
statements to see if I get any scroll events reported at all - and nothing shows up in the console.
Any idea what I'm doing wrong here?
UPDATE: Just to make sure that this works as a "non-AMP" page, I changed the line in the example above:
<script id="scroll-listener" type="text/plain" target="amp-script">...</script>
to this ...
<script id="scroll-listener" type="text/javascript">...</script>
and the site works as expected. So I know for sure that the javascript as written does what I want it to do. The issue is entirely with the way AMP is handling the script.
Apparently, you don't understand how amp-script works, which is strange, because there are examples in the official documentation.
Try this example:
The example above probably won't help you do what you want, but at least now you'll understand how amp-script works.
amp-script often requires a custom event to be triggered and will not work immediately after the page loads. Read about it here: https://amp.dev/documentation/components/amp-script/?format=websites#user-gestures
To complete this task, I recommend that you use the amp-position-observer and amp-animation components. Here is an example: