Can i use web components in AMP pages - javascript

I am trying to use web components in AMP page with amp-script but it's not working.
I am trying to add following code in index.html
<amp-script width="200" height="50" script="app-render">
<div id="app">loading...</div>
</amp-script>
<script id="app-render" type="text/plain" target="amp-script">
const app = document.getElementById('app');
app.innerHTML = <amp-news-container id="amp-news-container"></amp-news-container>;
</script>
But not working.
I also tried to add custom component into page but that creates error as custom component not allowed.
Is there any way i can use web components in AMP pages? no content or example found to user web components in AMP.
Adding whole index page -
<!DOCTYPE html>
<html ⚡️ lang="en" dir="ltl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>AMP Web Components</title>
<link rel="canonical" href="https://amp.dev/documentation/guides-and-tutorials/start/create/basic_markup/">
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<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>
<meta name="amp-script-src" content="sha384-N4a96F4jCQXTuaWhxfKGHDf9ZQmsqohVQd4GoJxNFVi1PznNK-wtSZXZuJTCettD" />
<script custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js" async=""></script>
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght#500;700&display=swap" rel="stylesheet">
</head>
<body class="news">
<amp-script width="200" height="50" script="app-render">
<div id="app">loading...</div>
</amp-script>
<script id="app-render" type="text/plain" target="amp-script">
const app = document.getElementById('app');
app.innerHTML = <amp-news-container id="amp-news-container"></amp-news-container>;
</script>
</body>
</html>
Here is my - amp-news-container.js
const ampNewsContainer = document.createElement('ampNewsContainer');
ampNewsContainer.innerHTML = `
<style>
</style>
<div class="amp-news-container">
<amp-news-header class="amp-news-header"></amp-news-header>
</div>
`;
class AmpNewsContainer extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(ampNewsContainer.cloneNode(true));
}
}
window.customElements.define('amp-news-container', AmpNewsContainer);
and
const ampNewsHeader = document.createElement('ampNewsHeader');
ampNewsHeader.innerHTML = `
<style>
</style>
<div class="amp-news-header">
<h1>Page header</h1>
</div>
`;
class AmpNewsHeader extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(ampNewsHeader.cloneNode(true));
}
}
window.customElements.define('amp-news-container', AmpNewsHeader);
But i am facing error while i am trying add/bind amp-news-container to body or div tag.
I can't use custom component directly in body as follow, it's giving AMP validation error as custom component not allowed.
The way i use web component in normal projects, add custom container component in index.html and import other sub models into same index page but no similar way found to use them in AMP.
Example of trying custom component in body -
<body class="afc-champions-league-news">
<div id="amp-news-container">
<amp-news-container id="amp-news-container"></amp-news-container>
</div>
<amp-script type="module" src="js/modules/news/components/amp-news-header.js" width="300" height="100">
</amp-script>
<amp-script type="module" src="js/modules/news/components/amp-news-container.js" width="300" height="100">
</amp-script> -->
</body>
no Clue if is there any way i can have these two integrated together.

Related

Playing CSS animation on button click won't work

I'm trying to call a CSS animation on the event that this button is pressed, after doing some research it seems classList is the way forward. It's late and I think I'm being stupid but I cannot get it to work.
HTML:
<body>
<img id="myID" class="mouse" src="mouse.png" onclick="ani()">
<script src="script.js"></script>
</body>
<head>
<link href="styles.css" rel="stylesheet"/>
</head>
JavaScript:
function ani()
{
document.getElementById('myID').classList.add = 'animate';
}
CSS:
.animate
{
animation: test 1s linear forwards;
}
#keyframes test
{
100%
{
transform: translateX(calc(8%));
}
}
add is a function so the way you are using classList needs a slight change from:
document.getElementById('myID').classList.add = 'animate';
to:
document.getElementById('myID').classList.add('animate');
function ani(){
document.getElementById('myID').classList.add('animate');
}
.animate {
animation: test 1s linear forwards;
}
#keyframes test {
100% {
transform: translateX(calc(8%));
}
}
<body>
<img id="myID" class="mouse" src="https://stock.wikimini.org/w/images/d/d4/Mickey_Mouse.png" onclick="ani()">
</body>

Start an animation after page loads on react

I am trying to make an element animate after the page loads on react, how do I do that please.
I'm new to react so I don't really know how to target the class and animation, but here is the
HTML and CSS
<div className="dangle" >
</div>
.dangle {
animation: swing ease-out 5s forwards;
float: left;
background-color: red;
}
link to codepen sample
Please I need the solution in react please
First, use "useState" to decide whether to apply animation. ( changing the state of the page )
Second, use "useEffect" to make the desired action run after the page loads. If you pass an empty array as the second parameter, the callback is executed only once after the page is loaded.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
</head>
<style>
body {background-color: powderblue; display:grid; place-items: center;}
#keyframes swing {
0% { transform: rotate(30deg); }
100% { transform: rotate(-30deg); }
}
.dangle {
animation: swing ease-out 5s forwards;
float: left;
background-color: red;
}
</style>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {animate: false};
}
componentDidMount(){
this.setState({animate: true})
}
render() {
return <div className={this.state.animate ? "dangle" : ""}>Hello</div>;
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
</script>
</body>
</html>
You can add a load event:
window.addEventListener('load', (event) => {
for (let dangle of document.querySelectorAll(".dangle")) dangle.classList.add("loaded");
});
and enhance the CSS to be executed, make sure the CSS is to be executed only when it's loaded:
.dangle.loaded {
animation: swing ease-out 5s forwards;
background-color: red;
height: 10rem;
width: 10rem;
}
and let's fix the HTML as well:
<div class="dangle" >
foo
</div>

AMP - manual trigger action on component

Is there any way to manual trigger action on AMP?
For example I have a carousel and I would like to manually change slide index
https://amp.dev/documentation/components/amp-carousel/?format=websites#gotoslide(index=integer)
there is a goToSlide action, but I only found execution on amp elements, but what if I would like to do this with VUE or VanillaJS? e.g.
<amp-carousel type="slides"
width="450"
height="300"
controls
loop
autoplay
delay="3000" data-next-button-aria-label="Go to next slide"
data-previous-button-aria-label="Go to previous slide"
role="region"
aria-label="Looping carousel">
<amp-img src="/static/inline-examples/images/image1.jpg"
width="450"
height="300"></amp-img>
<amp-img src="/static/inline-examples/images/image2.jpg"
width="450"
height="300"></amp-img>
<amp-img src="/static/inline-examples/images/image3.jpg"
width="450"
height="300"></amp-img>
</amp-carousel>
<button id="test">Change<button>
And JS Code:
const index = 10;
const button = document.querySelector('#button');
button.addEventListener('click', () => {
// trigger `goToSlide` with index arg
})
but what if I would like to do this with VUE or VanillaJS?
Then you should have tried amp-script right away.
My solution is not to use the goToSlide method, but to use the [slide] attribute(enabling amp-bind).
We create a local variable(amp-state), then use amp-script to change the value of this variable. For the carousel, the [slide] attribute will take the value of our local variable.
<!DOCTYPE html>
<html amp lang="en">
<head>
<meta charset="utf-8" />
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.2.js"></script>
<script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>
<meta name="amp-script-src" content="sha384-4UtnPtFFgGH7cYZgZV7ayJB7EQ9O4lK09yk4JpoBdinMiCGpq5M3nY0BaQ3NMhIR" />
<title>Hello, AMPs</title>
<link rel="canonical" href="https://amp.dev/documentation/guides-and-tutorials/start/create/basic_markup/" />
<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>
<style amp-custom>
</style>
</head>
<body>
<amp-state id="carouselState">
<script type="application/json">
{
"activeSlide": "1"
}
</script>
</amp-state>
<amp-script script="mySuperScript" layout="container">
<amp-carousel id="myCarousel" [slide]="carouselState.activeSlide" width="450" height="300" layout="fixed" type="slides" role="region" aria-label="Basic carousel">
<amp-img src="https://amp.dev/static/samples/img/image1.jpg" width="450" height="300"></amp-img>
<amp-img src="https://amp.dev/static/samples/img/image2.jpg" width="450" height="300"></amp-img>
<amp-img src="https://amp.dev/static/samples/img/image3.jpg" width="450" height="300"></amp-img>
</amp-carousel>
<button id="carouselBtn">Change Slide<button>
</amp-script>
<script id="mySuperScript" type="text/plain" target="amp-script">
let index = 2;
const button = document.querySelector('#carouselBtn');
button.addEventListener('click', () => {
AMP.setState({carouselState: {activeSlide: index } });
index = (index < 2 ? index + 1 : index - 2 );
});
</script>
</body>
</html>

How to use javascript with accelerated mobile page(AMP)?

I am trying to create an accelerated mobile page(AMP) using Javascript.
The AMP validator shows an error called "Custom JavaScript is not allowed".
I have tried below code.
<!doctype html>
<html amp>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="amp-script-src" content="sha384-vk5WoKIaW_vJyUAd9n_wmopsmNhiy-L2Z-SBxGYnUkunIxVxAv_UtMOhba_xskxh">
<title>Document</title>
<link rel="canonical" href="/" />
<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-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>
</head>
<body>
<amp-script script="local-script">
<button>Hello amp-script!</button>
</amp-script>
<script target="amp-script" type="text/plain" id="local-script">
console.log('js added')
</script>
</body>
</html>
I need to find some possible solution to work AMP with Javascript.
The AMP validator needs to be clean as it shows 1 error "Custom JavaScript is not allowed" which I am unable to find the cause from the above code.

Triggering CSS animation with JavaScript

I have this html
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="StyleSheet.css" rel="stylesheet" />
<link href="animation.css" rel="stylesheet" />
<meta charset="utf-8" />
</head>
<body>
<div class="box box-anim-start box-anim-end"></div>
<script src="jquery-2.1.4.min.js"></script>
<script src="JavaScript.js"></script>
</body>
</html>
As you can see there are two stylesheets linked to this page.
StyleSheet code
.box {
height: 100px;
width: 100px;
background-color: red;
}
animation code
.box-anim-start {
}
.box-anim-end {
transition-property: transform;
transition-duration: 2s;
transition-delay: 5s;
}
And here's the JavaScript code
var box = $(".box").eq(0);
var sheet = document.styleSheets[1];
var rules = sheet.cssRules || sheet.rules;
var rule0 = rules[0];
rule0.style.transform = "translateX(100px)";
var rule1 = rules[1];
rule1.style.transform = "translateX(0px)";
What I wanted was an animation upon opening this page. And, since the delay is mentioned in css, i thought that would work. But it didn't. Could you explain why?
It's makes a lot more sense to define your CSS animation in your CSS using keyframes, you can then call it in by adding a class to your box once the page has loaded.
So initially remove the .box-anim-start class
<div class="box"></div>
Then define the animation using keyframes:
#keyframes slide {
0%{
transform: translate(0, 0)
}
100% {
transform: translate(100px, 0)
}
}
Then call the animation within .box-anim-start
.box-anim-start {
animation: slide ease-in 2s;
animation-delay: 2s;
}
.box{
transition: 2s ease-in;
}
And finally add the class once the page has loaded using jQuery
$(document).ready(function){
$('.box').addClass('.box-anim-start');
});
The best way is to use the stylesheet.
In Chrome, for instance, your line:
var rules = sheet.cssRules || sheet.rules;
is wrong because rules is null. This happens because you need to change the index to
var sheet = document.styleSheets[0]; // instead of 1 in my case
But consider to put a delay between the two transition.
Instead, if you want simply use the js with your styles you can do:
$(function () {
$('div.box').css('transform', 'translateX(100px)').delay(3000).queue(function (next) {
$(this).css('transform', 'translateX(0px)');
next();
});
});
.box {
height: 100px;
width: 100px;
background-color: red;
}
.box-anim-start {
}
.box-anim-end {
transition-property: transform;
transition-duration: 1s;
transition-delay: 2s;
}
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<div class="box box-anim-start box-anim-end"></div>

Categories