AMP: amp-script no se está ejecutando
Estoy tratando de usar amp-scriptpara alternar una clase en mi nav(barra de menú superior) cuando la ventana comienza a desplazarse. El efecto es convertir el navegador fijo de semitransparente a blanco sólido.
Esto es lo que probé ...
<!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>
Desafortunadamente, el guión no tiene ningún efecto. También coloqué console.logdeclaraciones para ver si obtengo algún evento de desplazamiento informado, y no aparece nada en la consola.
¿Alguna idea de lo que estoy haciendo mal aquí?
ACTUALIZACIÓN: Solo para asegurarme de que esto funcione como una página "no AMP", cambié la línea en el ejemplo anterior:
<script id="scroll-listener" type="text/plain" target="amp-script">...</script>
a esto ...
<script id="scroll-listener" type="text/javascript">...</script>
y el sitio funciona como se esperaba. Entonces sé con certeza que el javascript tal como está escrito hace lo que quiero que haga. El problema está completamente en la forma en que AMP está manejando el script.
Respuestas
Aparentemente, no comprendes cómo funciona amp-script, lo cual es extraño, porque hay ejemplos en la documentación oficial.
Prueba este ejemplo:
<!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>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<meta name="amp-script-src" content="sha384-nPCFvs2yYOVX1DFcHvkEUY1aC6PdG8FAgPUG16rZwxfQJOPh_pM1rA-oUzDsg8pk" />
<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>
</head>
<body>
<amp-script script="scroll-listener">
<nav id="topnav">
<h1>ACME Inc.</h1>
</nav>
<main id="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>
</amp-script>
<script id="scroll-listener" type="text/plain" target="amp-script">
function myFunction(event) {
console.log('scrolled!!');
}
window.addEventListener("scroll", myFunction);
</script>
</body>
</html>
El ejemplo anterior probablemente no le ayudará a hacer lo que quiere, pero al menos ahora comprenderá cómo funciona amp-script.
amp-script a menudo requiere que se active un evento personalizado y no funcionará inmediatamente después de que se cargue la página. Lea sobre esto aquí:https://amp.dev/documentation/components/amp-script/?format=websites#user-gestures
Para completar esta tarea, le recomiendo que utilice los componentes amp-position-observer y amp-animation. Aquí hay un ejemplo:
<!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-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script>
<script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
<style amp-custom>
nav {
position: fixed;
top: 0;
width: 100vw;
color: cyan;
background-color: rgba(0, 0, 0, 0.2);
z-index: 10;
text-align: center;
}
h1 {
position: relative;
z-index: 2;
}
.opaque {
background-color: white;
color: black;
}
.hero {
height: max(25vh, 250px);
width: 100vw;
background: red;
}
.spacer {
height: 4em;
background: blue;
margin: 0.5em;
}
.scroll-effect {
background-color: #fff;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
.top-anchor {
position: relative;
}
</style>
</head>
<body>
<div class="top-anchor">
<amp-position-observer on="enter:hideAnim.start; exit:showAnim.start" layout="nodisplay"></amp-position-observer>
</div>
<nav id="topnav">
<span class="scroll-effect" id="scroll-effect"></span>
<h1>ACME Inc.</h1>
</nav>
<main id="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>
<amp-animation id="showAnim" layout="nodisplay">
<script type="application/json">
{
"duration": "200ms",
"fill": "both",
"iterations": "1",
"direction": "alternate",
"animations": [
{
"selector": "#scroll-effect",
"keyframes": [
{
"opacity": "1",
"visibility": "visible"
}
]
}
]
}
</script>
</amp-animation>
<amp-animation id="hideAnim" layout="nodisplay">
<script type="application/json">
{
"duration": "200ms",
"fill": "both",
"iterations": "1",
"direction": "alternate",
"animations": [
{
"selector": "#scroll-effect",
"keyframes": [{ "opacity": "0", "visibility": "hidden" }]
}
]
}
</script>
</amp-animation>
</body>
</html>