mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-12 10:00:39 -04:00
feat: add emoji reactor workshop (#61638)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com>
This commit is contained in:
@@ -3613,6 +3613,12 @@
|
||||
"In this workshop, you will build a storytelling app that will allow you to list different stories based on genre."
|
||||
]
|
||||
},
|
||||
"workshop-emoji-reactor": {
|
||||
"title": "Build an Emoji Reactor",
|
||||
"intro": [
|
||||
"In this workshop, you will build an emoji reactor to practice <code>querySelector</code> and <code>querySelectorAll</code>."
|
||||
]
|
||||
},
|
||||
"lab-favorite-icon-toggler": {
|
||||
"title": "Build a Favorite Icon Toggler",
|
||||
"intro": [
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Build an Emoji Reactor
|
||||
block: workshop-emoji-reactor
|
||||
superBlock: full-stack-developer
|
||||
---
|
||||
|
||||
## Introduction to the Build an Emoji Reactor
|
||||
|
||||
In this workshop, you will build an emoji reactor to practice `querySelector` and `querySelectorAll`.
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
id: 688c90634eb5ae69845ac35d
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
demoType: onLoad
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop you will create an Emoji Reactor App. The HTML boilerplate and all of the CSS has been provided for you.
|
||||
|
||||
Start by creating a `main` element.
|
||||
|
||||
Inside the `main` element create an `h1` element with a `class` of `title` and a text of `How are you feeling today?`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `main` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector("main"));
|
||||
```
|
||||
|
||||
You should have a `h1` as child of `main`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector("main > h1"));
|
||||
```
|
||||
|
||||
The `h1` element should have a class of `title`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("main > h1")?.className, "title");
|
||||
```
|
||||
|
||||
The `h1` element should contain the text `How are you feeling today?`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("main > h1")?.textContent.trim(), "How are you feeling today?");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
id: 6899b0d1825ff24e9fe8d747
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below the `h1` element, add a `p` element with class `description`.
|
||||
|
||||
Inside the `p` element write the text `Click on the buttons below to rate your emotions.`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a new `p` element below the `h1` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector("h1 + p"));
|
||||
```
|
||||
|
||||
The new `p` element should have a class of `description`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("h1 + p")?.className, "description");
|
||||
```
|
||||
|
||||
The new `p` element should have text of `Click on the buttons below to rate your emotions.`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("h1 + p")?.textContent.trim(), "Click on the buttons below to rate your emotions.");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
--fcc-editable-region--
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
--fcc-editable-region--
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,162 @@
|
||||
---
|
||||
id: 6899b1d3bb656e56bd6937e2
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below the `p` element, create a `div` element with the class `btn-container`.
|
||||
|
||||
Inside the `div` element, create a `button` element.
|
||||
|
||||
This `button` should have an `id` of `happy-btn`, a class of `emoji-btn` and an `aria-label` of `Happy face emoji`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Create a new `div` element below the `p` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector("p + div"));
|
||||
```
|
||||
|
||||
The new `div` element should have a class of `btn-container`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("p + div")?.className, "btn-container");
|
||||
```
|
||||
|
||||
There should be a `button` element inside the `div` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector("div > button"));
|
||||
```
|
||||
|
||||
The `button` element should have an `id` of `happy-btn`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("div > button")?.id, "happy-btn");
|
||||
```
|
||||
|
||||
The `button` element should have a `class` of `emoji-btn`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("div > button")?.className, "emoji-btn");
|
||||
```
|
||||
|
||||
The `button` element should have an `aria-label` of `Happy face emoji`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("div > button")?.getAttribute("aria-label"), "Happy face emoji");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
id: 6899b593d232e07617f74055
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `button` element, create a `span` element that contains `😊`
|
||||
|
||||
Give to the `span` element a `role` attribute with a value of `img` and an `aria-hidden` attribute with a value of `true`.
|
||||
|
||||
Then, create a second `span` element with a `class` of `count` containing the text `0/10`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Inside the `button` element there should be two `span` elements.
|
||||
|
||||
```js
|
||||
assert.lengthOf(document.querySelectorAll("button > span"), 2);
|
||||
```
|
||||
|
||||
The first `span` element should have a text content of `😊`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll("button > span")[0]?.textContent.trim(), "😊");
|
||||
```
|
||||
|
||||
The first `span` element should have a `role` attribute with value of `img`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll("button > span")[0]?.getAttribute("role"), "img");
|
||||
```
|
||||
|
||||
The first `span` element should have an `aria-hidden` attribute with value of `true`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll("button > span")[0]?.getAttribute("aria-hidden"), "true");
|
||||
```
|
||||
|
||||
The second `span` element should have a `class` attribute with value of `count`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll("button > span")[1]?.className, "count");
|
||||
```
|
||||
|
||||
The second `span` element should have a text content of `0/10`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll("button > span")[1]?.textContent.trim(), "0/10");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
--fcc-editable-region--
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
|
||||
</button>
|
||||
--fcc-editable-region--
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
id: 6899b7755876b10444ae3bcd
|
||||
title: Step 5
|
||||
challengeType: 0
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now it's time to link the JavaScript file.
|
||||
|
||||
Add a `script` element right before the closing tag of the `body` element with the right attribute and value to link the `script.js` file.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `script` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<script[^>]*>\s*<\/script>/);
|
||||
```
|
||||
|
||||
The `script` element should have a `src` of `./script.js`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<script\s*src\s*=\s*('|")(\.\/)?script\.js\1\s*>\s*<\/script>/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
id: 6899b84e392df30ae370985e
|
||||
title: Step 6
|
||||
challengeType: 0
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, in the JavaScript file, create an `happyBtn` variable.
|
||||
|
||||
Use `querySelector` to store a reference to the `#happy-btn` element in the `happyBtn` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a variable named `happyBtn`.
|
||||
|
||||
```js
|
||||
assert.exists(happyBtn);
|
||||
```
|
||||
|
||||
The `happyBtn` variable should hold a reference to the `#happy-btn` element.
|
||||
|
||||
```js
|
||||
assert.equal(happyBtn, document.querySelector("#happy-btn"));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
id: 6899c30b1d26094e11170c92
|
||||
title: Step 7
|
||||
challengeType: 0
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to add an event listener on the `happyBtn` element.
|
||||
|
||||
Write the event listener and its callback so that when the button is clicked the app will log to the console `Button clicked!`.
|
||||
|
||||
# --hints--
|
||||
|
||||
When the `happyBtn` is clicked, `Button clicked!` should be logged to the console.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
document.querySelector(`#happy-btn`).click();
|
||||
|
||||
assert.sameDeepOrderedMembers(spy.calls, [["Button clicked!"]]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
id: 689af0bf1c707336ee9a1842
|
||||
title: Step 8
|
||||
challengeType: 0
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now replace the content of the event listener callback.
|
||||
|
||||
Use `querySelector` to find the `.count` element within the button.
|
||||
|
||||
Then log the text content of the `.count` element when the button is clicked.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should log the text content of the `.count` element inside the clicked button.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
const testString = "teesting";
|
||||
document.querySelector("#happy-btn .count").textContent = testString;
|
||||
document.querySelector(`#happy-btn`).click();
|
||||
|
||||
assert.sameDeepOrderedMembers(spy.calls, [[testString]]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => {
|
||||
console.log("Button clicked!");
|
||||
})
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: 689b15aacce1ae176ec768dc
|
||||
title: Step 9
|
||||
challengeType: 0
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, you need to get the first number in the `0/10` text, in a way that will work even for `5/10` or `10/10`.
|
||||
|
||||
Parse the text content of the `.count` element to extract the current number.
|
||||
|
||||
Convert the count from a string to a number.
|
||||
|
||||
Log the current count in this format: `console.log("Current count:", currCount)`.
|
||||
|
||||
Hint: remember you can use the `split` method to divide a string into an array of substrings.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should log the current count as a number.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
document.querySelector(`#happy-btn`).click();
|
||||
|
||||
assert.sameDeepOrderedMembers(spy.calls[0], ["Current count:", 0]);
|
||||
```
|
||||
|
||||
You should log the current count as a number in a way that works for the various possible values.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
const testString = "5/10";
|
||||
document.querySelector("#happy-btn .count").textContent = testString;
|
||||
document.querySelector(`#happy-btn`).click();
|
||||
|
||||
assert.sameDeepOrderedMembers(spy.calls, [["Current count:", 5]]);
|
||||
|
||||
const testString2 = "10/10";
|
||||
document.querySelector("#happy-btn .count").textContent = testString2;
|
||||
document.querySelector(`#happy-btn`).click();
|
||||
|
||||
assert.sameDeepOrderedMembers(spy.calls[1], ["Current count:", 10]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => {
|
||||
const countEl = happyBtn.querySelector(".count");
|
||||
console.log(countEl.textContent);
|
||||
})
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
id: 689b17e7e63b8e2c13839e98
|
||||
title: Step 10
|
||||
challengeType: 0
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now it's time to implement the actual counting functionality.
|
||||
|
||||
Instead of just logging the current count, you need to increment it and update the display.
|
||||
|
||||
Remove the `console.log`.
|
||||
|
||||
Check if the current first number inside the `.count` is already 10 (the text is `10/10`), and if so, do nothing.
|
||||
|
||||
If the number is less then 10, increment the current count by 1 and update the text of the `.count` element. For example, if the current count is 2, it should be incremented to 3 and the text for the `.count` element should be `3/10`.
|
||||
|
||||
# --hints--
|
||||
|
||||
When the button is clicked, the count should increment from 0 to 1.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
const countEl = document.querySelector("#happy-btn .count");
|
||||
countEl.textContent = "0/10";
|
||||
document.querySelector("#happy-btn").click();
|
||||
assert.equal(countEl.textContent, "1/10");
|
||||
```
|
||||
|
||||
When the button is clicked multiple times, the count should increment properly.
|
||||
|
||||
```js
|
||||
const countEl = document.querySelector("#happy-btn .count");
|
||||
countEl.textContent = "3/10";
|
||||
document.querySelector("#happy-btn").click();
|
||||
assert.equal(countEl.textContent, "4/10");
|
||||
```
|
||||
|
||||
When the count is already at 10, clicking should not increment it further.
|
||||
|
||||
```js
|
||||
const countEl = document.querySelector("#happy-btn .count");
|
||||
countEl.textContent = "10/10";
|
||||
document.querySelector("#happy-btn").click();
|
||||
assert.equal(countEl.textContent, "10/10");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => {
|
||||
const countEl = happyBtn.querySelector(".count");
|
||||
const currCount = +countEl.textContent.split("/")[0];
|
||||
console.log("Current count:", currCount);
|
||||
})
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: 68a9f8378ddba1261a268cce
|
||||
title: Step 11
|
||||
challengeType: 0
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You can make the code more reusable.
|
||||
|
||||
Create a function called `updateCount` that takes a button element as a parameter.
|
||||
|
||||
This function should contain all the logic for updating a button's count: finding the count element, parsing the current count, checking if it's at the maximum, incrementing, and updating the display.
|
||||
|
||||
Then update your event listener callback to call `updateCount(happyBtn)` instead of having the logic inline.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `updateCount`.
|
||||
|
||||
```js
|
||||
assert.isFunction(updateCount);
|
||||
```
|
||||
|
||||
The `updateCount` function should take a button parameter.
|
||||
|
||||
```js
|
||||
assert.equal(updateCount.length, 1);
|
||||
```
|
||||
|
||||
The `updateCount` function should work correctly with any button element.
|
||||
|
||||
```js
|
||||
const testBtn = document.createElement("button");
|
||||
testBtn.innerHTML = '<span class="count">3/10</span>';
|
||||
updateCount(testBtn);
|
||||
assert.equal(testBtn.querySelector(".count").textContent, "4/10");
|
||||
```
|
||||
|
||||
Your event listener should call `updateCount` with the button as an argument.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(window, "updateCount");
|
||||
document.querySelector("#happy-btn").click();
|
||||
assert.equal(spy.calls.length, 1);
|
||||
assert.equal(spy.calls[0][0], document.querySelector("#happy-btn"));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => {
|
||||
const countEl = happyBtn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
})
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,234 @@
|
||||
---
|
||||
id: 68a9fa161498c3324ac06fe1
|
||||
title: Step 12
|
||||
challengeType: 0
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
It's time to start working on the other buttons. The remaining `button` elements have been added for you in the HTML file.
|
||||
|
||||
For each new button (`#confused-btn`, `#sad-btn` and `#loving-btn`), select it using `querySelector` with its ID, then add a click event listener that calls `updateCount` with that button.
|
||||
|
||||
Use the variable names `confusedBtn`, `sadBtn`, `lovingBtn`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a variable named `confusedBtn`.
|
||||
|
||||
```js
|
||||
assert.exists(confusedBtn);
|
||||
```
|
||||
|
||||
You should store the `#confused-btn` element in the `confusedBtn` variable.
|
||||
|
||||
```js
|
||||
assert.equal(confusedBtn, document.querySelector('#confused-btn'));
|
||||
```
|
||||
|
||||
You should create a variable named `sadBtn`.
|
||||
|
||||
```js
|
||||
assert.exists(sadBtn);
|
||||
```
|
||||
|
||||
You should store the `#sad-btn` element in the `sadBtn` variable.
|
||||
|
||||
```js
|
||||
assert.equal(sadBtn, document.querySelector('#sad-btn'));
|
||||
```
|
||||
|
||||
You should create a variable named `lovingBtn`.
|
||||
|
||||
```js
|
||||
assert.exists(lovingBtn);
|
||||
```
|
||||
|
||||
You should store the `#loving-btn` element in the `lovingBtn` variable.
|
||||
|
||||
```js
|
||||
assert.equal(lovingBtn, document.querySelector('#loving-btn'));
|
||||
```
|
||||
|
||||
The `#confused-btn` element should have a click event listener that calls `updateCount`.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(window, "updateCount");
|
||||
document.querySelector("#confused-btn").click();
|
||||
assert.equal(spy.calls.length, 1);
|
||||
assert.equal(spy.calls[0][0], document.querySelector("#confused-btn"));
|
||||
```
|
||||
|
||||
The `#sad-btn` element should have a click event listener that calls `updateCount`.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(window, "updateCount");
|
||||
document.querySelector("#sad-btn").click();
|
||||
assert.equal(spy.calls.length, 1);
|
||||
assert.equal(spy.calls[0][0], document.querySelector("#sad-btn"));
|
||||
```
|
||||
|
||||
The `#loving-btn` element should have a click event listener that calls `updateCount`.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(window, "updateCount");
|
||||
document.querySelector("#loving-btn").click();
|
||||
assert.equal(spy.calls.length, 1);
|
||||
assert.equal(spy.calls[0][0], document.querySelector("#loving-btn"));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="confused-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Confused face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😕</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button id="sad-btn" class="emoji-btn" aria-label="Angry face emoji">
|
||||
<span role="img" aria-hidden="true">😠</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="loving-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Loving face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😍</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
function updateCount(btn) {
|
||||
const countEl = btn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
}
|
||||
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => updateCount(happyBtn));
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
id: 68a9fa1787009f3293b7ba7f
|
||||
title: Step 13
|
||||
challengeType: 0
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You've probably noticed that your code is getting quite repetitive! There's a better way to handle multiple similar elements.
|
||||
|
||||
Instead of selecting each button individually, use `querySelectorAll(".emoji-btn")` to select all buttons with the class `emoji-btn` at once. Store the result in a variable called `btns`.
|
||||
|
||||
# --before-all--
|
||||
|
||||
```js
|
||||
const loggedValues = [];
|
||||
const originalConsoleLog = console.log;
|
||||
console.log = (...args) => {
|
||||
loggedValues.push(args);
|
||||
originalConsoleLog(...args);
|
||||
};
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `querySelectorAll` to select all emoji buttons.
|
||||
|
||||
```js
|
||||
assert.match(code, /document\.querySelectorAll\s*\(\s*['"`]\.emoji-btn['"`]\s*\)/);
|
||||
```
|
||||
|
||||
You should store the result in a variable called `btns`.
|
||||
|
||||
```js
|
||||
assert.isDefined(btns, 'You should create a variable called btns');
|
||||
assert.isTrue(btns instanceof NodeList, 'btns should be a NodeList from querySelectorAll');
|
||||
```
|
||||
|
||||
The `btns` variable should contain all 4 emoji buttons.
|
||||
|
||||
```js
|
||||
assert.equal(btns.length, 4, 'btns should contain all 4 emoji buttons');
|
||||
assert.equal(btns[0].id, 'happy-btn', 'First button should be the happy button');
|
||||
assert.equal(btns[1].id, 'confused-btn', 'Second button should be the confused button');
|
||||
assert.equal(btns[2].id, 'sad-btn', 'Third button should be the sad button');
|
||||
assert.equal(btns[3].id, 'loving-btn', 'Fourth button should be the loving button');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="confused-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Confused face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😕</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button id="sad-btn" class="emoji-btn" aria-label="Angry face emoji">
|
||||
<span role="img" aria-hidden="true">😠</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="loving-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Loving face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😍</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
function updateCount(btn) {
|
||||
const countEl = btn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
}
|
||||
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
const confusedBtn = document.querySelector("#confused-btn");
|
||||
const sadBtn = document.querySelector("#sad-btn");
|
||||
const lovingBtn = document.querySelector("#loving-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => updateCount(happyBtn));
|
||||
confusedBtn.addEventListener("click", () => updateCount(confusedBtn));
|
||||
sadBtn.addEventListener("click", () => updateCount(sadBtn));
|
||||
lovingBtn.addEventListener("click", () => updateCount(lovingBtn));
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,336 @@
|
||||
---
|
||||
id: 68a9fa18ad7a8432d0fc8621
|
||||
title: Step 15
|
||||
challengeType: 0
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In the lectures you learned that `querySelectorAll` returns a `NodeList`, which is an array-like structure, and one of the methods that a `NodeList` has is `forEach()`, and it works the same way as the `forEach` that exists on arrays.
|
||||
|
||||
Iterate over `btns` with a `forEach()` that adds the same event listener to each button.
|
||||
|
||||
Use a callback function that takes a `btn` parameter, and inside the callback, add a click event listener that calls `updateCount(btn)`.
|
||||
|
||||
With this you have finished the workshop.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `btns.forEach()` to iterate over the buttons.
|
||||
|
||||
```js
|
||||
assert.match(code, /btns\.forEach\s*\(/);
|
||||
```
|
||||
|
||||
All buttons should have event listeners that call `updateCount` when clicked.
|
||||
|
||||
```js
|
||||
// Test that clicking each button calls updateCount
|
||||
const spy = __helpers.spyOn(window, "updateCount");
|
||||
document.querySelector("#happy-btn").click();
|
||||
document.querySelector("#confused-btn").click();
|
||||
document.querySelector("#sad-btn").click();
|
||||
document.querySelector("#loving-btn").click();
|
||||
assert.lengthOf(spy.calls, 4);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="confused-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Confused face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😕</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button id="sad-btn" class="emoji-btn" aria-label="Angry face emoji">
|
||||
<span role="img" aria-hidden="true">😠</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="loving-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Loving face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😍</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
function updateCount(btn) {
|
||||
const countEl = btn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
const btns = document.querySelectorAll(".emoji-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="confused-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Confused face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😕</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button id="sad-btn" class="emoji-btn" aria-label="Angry face emoji">
|
||||
<span role="img" aria-hidden="true">😠</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="loving-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Loving face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😍</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
function updateCount(btn) {
|
||||
const countEl = btn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
}
|
||||
|
||||
const btns = document.querySelectorAll(".emoji-btn");
|
||||
|
||||
btns.forEach((btn) => btn.addEventListener("click", () => updateCount(btn)));
|
||||
```
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
id: 68a9fa1976616e330813a96c
|
||||
title: Step 14
|
||||
challengeType: 0
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now make some space, remove all the button variables and the `eventListener` you have created for each.
|
||||
|
||||
# --hints--
|
||||
|
||||
The `happyBtn` variable should not exist.
|
||||
|
||||
```js
|
||||
try {
|
||||
happyBtn;
|
||||
assert.fail('happyBtn variable should not exist');
|
||||
} catch (e) {
|
||||
assert.equal(e.name, 'ReferenceError', 'happyBtn variable should not exist');
|
||||
}
|
||||
```
|
||||
|
||||
The `confusedBtn` variable should not exist.
|
||||
|
||||
```js
|
||||
try {
|
||||
confusedBtn;
|
||||
assert.fail('confusedBtn variable should not exist');
|
||||
} catch (e) {
|
||||
assert.equal(e.name, 'ReferenceError', 'confusedBtn variable should not exist');
|
||||
}
|
||||
```
|
||||
|
||||
The `saddBtn` variable should not exist.
|
||||
|
||||
```js
|
||||
try {
|
||||
sadBtn;
|
||||
assert.fail('sadBtn variable should not exist');
|
||||
} catch (e) {
|
||||
assert.equal(e.name, 'ReferenceError', 'sadBtn variable should not exist');
|
||||
}
|
||||
```
|
||||
|
||||
The `lovingBtn` variable should not exist.
|
||||
|
||||
```js
|
||||
try {
|
||||
lovingBtn;
|
||||
assert.fail('lovingBtn variable should not exist');
|
||||
} catch (e) {
|
||||
assert.equal(e.name, 'ReferenceError', 'lovingBtn variable should not exist');
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Emoji Reactor</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
<h1 class="title">How are you feeling today?</h1>
|
||||
|
||||
<p class="description">
|
||||
Click on the buttons below to rate your emotions.
|
||||
</p>
|
||||
<div class="btn-container">
|
||||
<button id="happy-btn" class="emoji-btn" aria-label="Happy face emoji">
|
||||
<span role="img" aria-hidden="true">😊</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="confused-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Confused face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😕</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button id="sad-btn" class="emoji-btn" aria-label="Angry face emoji">
|
||||
<span role="img" aria-hidden="true">😠</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
<button
|
||||
id="loving-btn"
|
||||
class="emoji-btn"
|
||||
aria-label="Loving face emoji"
|
||||
>
|
||||
<span role="img" aria-hidden="true">😍</span>
|
||||
<span class="count">0/10</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #efefef;
|
||||
--white: #ffffff;
|
||||
--very-dark-blue: #0a0a23;
|
||||
--light-purple: #a78bfa;
|
||||
--very-light-purple: #c4b5fd;
|
||||
--purple: #8b5cf6;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--very-dark-blue);
|
||||
color: var(--light-grey);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-container,
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.emoji-btn {
|
||||
width: 70%;
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background-color: var(--light-purple);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
var(--very-light-purple),
|
||||
var(--light-purple)
|
||||
);
|
||||
border: 3px solid var(--purple);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-size: 1.5rem;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.emoji-btn {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-btn:hover {
|
||||
background-color: var(--purple);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.4rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
function updateCount(btn) {
|
||||
const countEl = btn.querySelector(".count");
|
||||
let currCount = +countEl.textContent.split("/")[0];
|
||||
|
||||
if (currCount === 10) return;
|
||||
|
||||
currCount++;
|
||||
|
||||
countEl.textContent = `${currCount}/10`;
|
||||
}
|
||||
|
||||
|
||||
const btns = document.querySelectorAll(".emoji-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
const happyBtn = document.querySelector("#happy-btn");
|
||||
const confusedBtn = document.querySelector("#confused-btn");
|
||||
const sadBtn = document.querySelector("#sad-btn");
|
||||
const lovingBtn = document.querySelector("#loving-btn");
|
||||
|
||||
happyBtn.addEventListener("click", () => updateCount(happyBtn));
|
||||
confusedBtn.addEventListener("click", () => updateCount(confusedBtn));
|
||||
sadBtn.addEventListener("click", () => updateCount(sadBtn));
|
||||
lovingBtn.addEventListener("click", () => updateCount(lovingBtn));
|
||||
--fcc-editable-region--
|
||||
```
|
||||
72
curriculum/structure/blocks/workshop-emoji-reactor.json
Normal file
72
curriculum/structure/blocks/workshop-emoji-reactor.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "Build an Emoji Reactor",
|
||||
"blockType": "workshop",
|
||||
"blockLayout": "challenge-grid",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "workshop-emoji-reactor",
|
||||
"helpCategory": "JavaScript",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "688c90634eb5ae69845ac35d",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "6899b0d1825ff24e9fe8d747",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "6899b1d3bb656e56bd6937e2",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "6899b593d232e07617f74055",
|
||||
"title": "Step 4"
|
||||
},
|
||||
{
|
||||
"id": "6899b7755876b10444ae3bcd",
|
||||
"title": "Step 5"
|
||||
},
|
||||
{
|
||||
"id": "6899b84e392df30ae370985e",
|
||||
"title": "Step 6"
|
||||
},
|
||||
{
|
||||
"id": "6899c30b1d26094e11170c92",
|
||||
"title": "Step 7"
|
||||
},
|
||||
{
|
||||
"id": "689af0bf1c707336ee9a1842",
|
||||
"title": "Step 8"
|
||||
},
|
||||
{
|
||||
"id": "689b15aacce1ae176ec768dc",
|
||||
"title": "Step 9"
|
||||
},
|
||||
{
|
||||
"id": "689b17e7e63b8e2c13839e98",
|
||||
"title": "Step 10"
|
||||
},
|
||||
{
|
||||
"id": "68a9f8378ddba1261a268cce",
|
||||
"title": "Step 11"
|
||||
},
|
||||
{
|
||||
"id": "68a9fa161498c3324ac06fe1",
|
||||
"title": "Step 12"
|
||||
},
|
||||
{
|
||||
"id": "68a9fa1787009f3293b7ba7f",
|
||||
"title": "Step 13"
|
||||
},
|
||||
{
|
||||
"id": "68a9fa1976616e330813a96c",
|
||||
"title": "Step 14"
|
||||
},
|
||||
{
|
||||
"id": "68a9fa18ad7a8432d0fc8621",
|
||||
"title": "Step 15"
|
||||
}
|
||||
],
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true
|
||||
}
|
||||
@@ -421,6 +421,7 @@
|
||||
"blocks": [
|
||||
"lecture-working-with-the-dom-click-events-and-web-apis",
|
||||
"workshop-storytelling-app",
|
||||
"workshop-emoji-reactor",
|
||||
"lab-favorite-icon-toggler",
|
||||
"lecture-understanding-the-event-object-and-event-delegation",
|
||||
"workshop-music-instrument-filter",
|
||||
|
||||
Reference in New Issue
Block a user