let myLibrary = [
{
id: 0,
title: "The Once and Future King",
author: "White",
pages: 654,
read: false,
},
{
id: 1,
title: "The Hobbit",
author: "Tolkien",
pages: 304,
read: false,
},
];
const bookContent = document.getElementById("content");
function displayBook(book) {
const addBook = document.createElement("div");
addBook.className = "book";
addBook.id = book.id;
bookContent.appendChild(addBook);
addBook.innerHTML = `
<div class="title">
<p class="bookTitle">
<span>${book.title}</span>
</p>
</div>
<div class="body">
<p>
Author: <span>${book.author}</span>
</p>
<p>
Pages: <span>${book.pages}</span>
</p>
</div>
<div class="read">
<label class="switch" data-book="0">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
<div class="delete">
<button class="delete-btn">DELETE</button>
</div>`;
}
// Display your original object list
myLibrary.forEach((book) => {
displayBook(book);
});
// Handle your object creation
const form = document.getElementById("form");
form.addEventListener("submit", updateLibrary);
function updateLibrary(event) {
// Need this so it doesn't refresh page
event.preventDefault();
const title = document.getElementById("title").value;
const author = document.getElementById("author").value;
const pages = document.getElementById("pages").value;
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
// Adds object to array
myLibrary.push(book);
// Displays new book
displayBook(book);
// Reset form
resetForm();
// Close form
document.getElementById("addBookForm").style.display = "none";
console.log(myLibrary);
}
// Resets the form so user can input another book
function resetForm() {
document.getElementById("form").reset();
}
// The form is automatically set to hidden. This loads it up for the user
const openForm = function () {
document.getElementById("addBookForm").style.display = "block";
document.getElementById("title").focus();
};
// Sets the form display back to none
const closeForm = () =>
(document.getElementById("addBookForm").style.display = "none");
/* .main {
} */
.header {
display: flex;
flex-direction: column;
background-color: #c689c6;
height: 150px;
border: 1px solid #3b133b;
}
.btn {
margin: 0 auto;
margin-top: 55px;
display: block;
text-align: center;
background-color: #4649ff;
padding: 0.75rem 1.25rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
font-size: 1rem;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.btn:hover {
background-color: #3134fa;
}
.content {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
justify-content: flex-start;
background-color: #fffdfa;
height: auto;
}
.book {
border: 2px solid #ffa94d;
background-color: #ffd8a8;
color: #d9480f;
width: 280px;
height: 365px;
margin: 10px;
}
.title {
border-bottom: 2px solid #ffa94d;
}
.title p {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-size: larger;
}
.title span {
color: #3c4048;
}
.body {
border: 1px solid transparent;
height: 200px;
background-color: #fff4e6;
}
.body p {
padding-left: 20px;
}
p span {
color: #3c4048;
}
.read {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
border-top: 2px solid #ffa94d;
text-align: center;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #3d8361;
}
input:focus + .slider {
box-shadow: 0 0 1px #3d8361;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.delete {
height: 50px;
border-top: 2px solid #ffa94d;
}
.delete-btn {
margin: 0 auto;
margin-top: 8px;
display: block;
text-align: center;
background-color: #e94560;
padding: 0.5rem 0.75rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.delete-btn:hover {
background-color: #e7082d;
}
.close-btn {
color: #e7082d;
font-size: large;
background-color: #c689c6;
border: none;
float: right;
cursor: pointer;
}
/* THE FORM */
.form-content {
display: flex;
justify-content: center;
}
.form {
display: none;
position: fixed;
margin-top: 5px;
border: 2px solid #3b133b;
animation: openForm 0.5s;
z-index: 1;
}
#keyframes openForm {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.form h1 {
text-align: center;
}
.form-container {
background-color: #c689c6;
border: 2px solid black;
max-width: 300px;
padding: 10px;
}
.form-container h1 {
padding-left: 20px;
}
.form-container input[type="text"],
.form-container input[type="number"] {
width: 80%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
}
.form-container input[type="text"]:focus,
.form-container input[type="number"]:focus {
outline: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Library</title>
</head>
<body>
<div class="main">
<div class="header">
<button class="btn" id="btn" onclick="openForm()">Add a Book</button>
</div>
<div class="form-content">
<div class="form" id="addBookForm">
<form id="form" action="" class="form-container">
<button type="button" class="close-btn" onclick="closeForm()">
x
</button>
<h1>Add a Book</h1>
<label for="title">Title</label>
<input
type="text"
placeholder="Title"
name="title"
id="title"
required
/>
<label for="author">Author</label>
<input
type="text"
placeholder="Author"
name="author"
id="author"
required
/>
<label for="pages">Pages</label>
<input
type="number"
placeholder="Pages"
name="pages"
required
id="pages"
/>
<button type="submit" id="submit-btn">Submit</button>
</form>
</div>
</div>
<div id="content" class="content"></div>
</div>
</body>
</html>
I have a form where the user inputs information from a book they are reading and upon hitting submit, the information is sent as its own object inside an array. I also have a forEach method running which loops through the array and displays each object as a div on the web page.
let myLibrary = [];
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
myLibrary.push(book)
As you can see from the code above, the three properties that the user fills out are the books title, author and page count. There's also a property that is automatically added called the read property and it is automatically set as false.
The Problem
My problem is this. I have the following code displayed at the bottom of each div.
<div class="read">
<label class="switch">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
This code is very simple. It's a toggle switch which I found here.
I want it so when the toggle switch is grayed out, the read status is set to false. But when the toggle switch is turned on, the read property is set to true. I am having a very difficult time figuring out how to get this done.
What I've Tried
I was able to use an onclick to select the toggle switch's parent element, and I tested it using console.log however I am unsure of where to go from there. I attempted to update the book.read to true using the ternary operator but it was out of scope and resulted in an error.
document.querySelector(".main").onclick = (ev) => {
let el = ev.target.classList.contains("switch")
? ev.target.parentElement
: ev.target.classList.contains("slider")
? ev.target
: false;
if (el) {
let toggle = el.parentElement.parentElement.parentElement;
let index = [...toggle.parentElement.children].indexOf(toggle);
myLibrary[index].read = false ? false : true;
console.log(myLibrary[index].read);
}
console.log(myLibrary);
};
Change this
function displayBook(book) {
...
<label class="switch" data-book="0">
to
function displayBook(book,bookIndex) {
...
<label class="switch" data-book="${bookIndex}">
and
myLibrary.forEach((book) => {
displayBook(book);
});
to
myLibrary.forEach((book,i) => {
displayBook(book,i);
});
lastly change
// Displays new book
displayBook(book);
to
// Displays new book
displayBook(book,myLibrary.length-1);
Here is the code inclusive a delete function
It would be slightly simpler if we had an associate array on book_id
Note I removed the numeric ID because it is not needed since the index of the array is the same
let myLibrary = [{
title: "The Once and Future King",
author: "White",
pages: 654,
read: false,
},
{
title: "The Hobbit",
author: "Tolkien",
pages: 304,
read: false,
},
];
const bookContent = document.getElementById("content");
const formDiv = document.getElementById("addBookForm");
function displayBook(book, idx) {
const addBook = document.createElement("div");
addBook.className = "book";
addBook.id = `book_${idx}`;
bookContent.appendChild(addBook);
addBook.innerHTML = `
<div class="title">
<p class="bookTitle">
<span>${book.title}</span>
</p>
</div>
<div class="body">
<p>
Author: <span>${book.author}</span>
</p>
<p>
Pages: <span>${book.pages}</span>
</p>
</div>
<div class="read">
<label class="switch" data-book="${idx}">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
<div class="delete">
<button class="delete-btn">DELETE</button>
</div>`;
}
// Display your original object list
myLibrary.forEach((book, i) => {
displayBook(book, i);
});
const deleteBook = (e) => {
const parent = e.target.closest("div.book");
const idx = parent.querySelector(".switch").dataset.book;
parent.remove();
console.log(idx);
myLibrary.splice(idx, 1);
console.log(myLibrary);
content.querySelectorAll("div.book").forEach((book, i) => { // reset the hard way
book.id = `book_${i}`;
book.querySelector("label.switch").dataset.book = i;
})
};
content.addEventListener("click", function(e) {
const tgt = e.target;
if (!tgt.matches(".delete-btn")) return; // not the delete
deleteBook(e); // pass the event to the delete
})
// Handle your object creation
const form = document.getElementById("form");
form.addEventListener("submit", updateLibrary);
function updateLibrary(event) {
// Need this so it doesn't refresh page
event.preventDefault();
const title = document.getElementById("title").value;
const author = document.getElementById("author").value;
const pages = document.getElementById("pages").value;
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
// Adds object to array
myLibrary.push(book);
// Displays new book
displayBook(book);
// Reset form
resetForm();
// Close form
formDiv.style.display = "none";
console.log(myLibrary);
}
// Resets the form so user can input another book
function resetForm() {
document.getElementById("form").reset();
}
// The form is automatically set to hidden. This loads it up for the user
const openForm = function() {
formDiv.style.display = "block";
document.getElementById("title").focus();
};
// Sets the form display back to none
const closeForm = () => formDiv.style.display = "none";
/* .main {
} */
.header {
display: flex;
flex-direction: column;
background-color: #c689c6;
height: 150px;
border: 1px solid #3b133b;
}
.btn {
margin: 0 auto;
margin-top: 55px;
display: block;
text-align: center;
background-color: #4649ff;
padding: 0.75rem 1.25rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
font-size: 1rem;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.btn:hover {
background-color: #3134fa;
}
.content {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
justify-content: flex-start;
background-color: #fffdfa;
height: auto;
}
.book {
border: 2px solid #ffa94d;
background-color: #ffd8a8;
color: #d9480f;
width: 280px;
height: 365px;
margin: 10px;
}
.title {
border-bottom: 2px solid #ffa94d;
}
.title p {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-size: larger;
}
.title span {
color: #3c4048;
}
.body {
border: 1px solid transparent;
height: 200px;
background-color: #fff4e6;
}
.body p {
padding-left: 20px;
}
p span {
color: #3c4048;
}
.read {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
border-top: 2px solid #ffa94d;
text-align: center;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked+.slider {
background-color: #3d8361;
}
input:focus+.slider {
box-shadow: 0 0 1px #3d8361;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.delete {
height: 50px;
border-top: 2px solid #ffa94d;
}
.delete-btn {
margin: 0 auto;
margin-top: 8px;
display: block;
text-align: center;
background-color: #e94560;
padding: 0.5rem 0.75rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.delete-btn:hover {
background-color: #e7082d;
}
.close-btn {
color: #e7082d;
font-size: large;
background-color: #c689c6;
border: none;
float: right;
cursor: pointer;
}
/* THE FORM */
.form-content {
display: flex;
justify-content: center;
}
.form {
display: none;
position: fixed;
margin-top: 5px;
border: 2px solid #3b133b;
animation: openForm 0.5s;
z-index: 1;
}
#keyframes openForm {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.form h1 {
text-align: center;
}
.form-container {
background-color: #c689c6;
border: 2px solid black;
max-width: 300px;
padding: 10px;
}
.form-container h1 {
padding-left: 20px;
}
.form-container input[type="text"],
.form-container input[type="number"] {
width: 80%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
}
.form-container input[type="text"]:focus,
.form-container input[type="number"]:focus {
outline: none;
}
<div class="main">
<div class="header">
<button class="btn" id="btn" onclick="openForm()">Add a Book</button>
</div>
<div class="form-content">
<div class="form" id="addBookForm">
<form id="form" action="" class="form-container">
<button type="button" class="close-btn" onclick="closeForm()">
x
</button>
<h1>Add a Book</h1>
<label for="title">Title</label>
<input type="text" placeholder="Title" name="title" id="title" required />
<label for="author">Author</label>
<input type="text" placeholder="Author" name="author" id="author" required />
<label for="pages">Pages</label>
<input type="number" placeholder="Pages" name="pages" required id="pages" />
<button type="submit" id="submit-btn">Submit</button>
</form>
</div>
</div>
<div id="content" class="content"></div>
</div>
Related
// GET
const getAdviceNumber = document.querySelector('#adviceNumber');
const adviceResultsDiv = document.querySelector('#adviceResults');
const diceBtn = document.querySelector('#spinDice');
const staticText = document.querySelector('#static');
const favouriteSection = document.querySelector('.favouriteSection')
diceBtn.addEventListener('click', () => {
const getAPI = async () => {
// Call API
/* eslint-disable */
const res = await axios.get('https://api.adviceslip.com/advice');
// remove static text
staticText.remove();
// Generate spin on btn
const element = document.querySelector('#spinDice');
element.classList.add('rotateMe');
setTimeout(() => element.classList.remove('rotateMe'), 800);
// generate unique id number
const header = document.createElement('h1');
header.className = 'title';
header.append(` ADVICE # ${res.data.slip.id}`);
while (getAdviceNumber.childElementCount > 0) {
getAdviceNumber.firstChild.remove();
}
getAdviceNumber.append(header);
// generate unique advice
const para = document.createElement('p');
para.className = 'para';
para.append(`"${res.data.slip.advice}"`);
while (adviceResultsDiv.childElementCount > 0) {
adviceResultsDiv.firstChild.remove();
}
adviceResultsDiv.append(para);
//generate add to favourites button
const addFavourite = document.createElement('p');
addFavourite.className = 'fav';
addFavourite.innerHTML = `<p>Add to Favourites<i class="fa-solid fa-folder-plus"></i></p>`;
while (favouriteSection.childElementCount > 0) {
favouriteSection.firstChild.remove();
}
favouriteSection.append(addFavourite)
};
getAPI();
favouriteSection.addEventListener('click', () => {
const favouriteItem = document.createElement('p');
favouriteItem.innerHTML = `<p class="icons"><i class="fa-solid fa-magnifying-glass"></i> <i class="fa-solid fa-trash-can"></i></p>`
favouriteItem.className = 'favouriteItemBorder';
favouriteSection.append(favouriteItem)
favouriteItem.append(`${getAdviceNumber.textContent}: ${ adviceResultsDiv.textContent}`)
})
});
body {
background-color: hsl(218, 23%, 16%);
font-family: Arial, Helvetica, sans-serif;
}
#advice-container {
background-color: hsl(217, 19%, 38%);
border-radius: 20px;
position: absolute;
-ms-transform: translateY(-50%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
padding-bottom: 40px;
}
h2 {
color: hsl(193, 38%, 86%);
text-align: center;
}
.title {
color: hsl(150, 100%, 66%);
font-size: 15px;
text-align: center;
margin-top: 20px;
}
.para {
color: hsl(193, 38%, 86%);
font-size: 28px;
font-weight: 500;
text-align: center;
margin: 20px 20px 0 20px;
}
.btn {
margin-top: 40px;
margin-bottom: -75px;
}
.dice-container {
background-color: hsl(150, 100%, 66%);
border: solid 2px hsl(193, 38%, 86%);
border-radius: 33px;
margin: 20px 110px 0 110px;
}
.dice-container:hover {
box-shadow: 0 0 30px -2px #52ffa8;
}
.fa-dice-five {
font-size: 50px;
width: 100%;
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
padding-right: 10px;
/* transform: rotate(90deg); */
}
.rotate {
transition: all 0s ease;
transform: rotate(0deg);
}
.rotateMe {
transition: all 0.3s ease;
transform: rotate(90deg);
}
#icons {
color: hsl(193, 38%, 86%);
}
.icon-container {
padding: 20px 120px 0 120px;
width: 100%;
}
.fa-grip-lines-vertical {
margin: 0 10px 0 10px;
}
.line {
width: 100%;
}
.favouriteSection {
position: absolute;
top: 70%;
}
.fav {
color: #52ffa8;
font-size: 32px;
margin: 20px;
}
.fa-folder-plus {
margin-left: 10px;
}
.favouriteItemBorder {
border: 2px solid white;
width: 300px;
height: 60px;
margin: 20px;
padding: 10px;
text-align: center;
}
.icons {
position:absolute;
bottom:10px;
left: 40%;
font-size: 20px;
}
/* desktop ..................................................................................... */
#media screen and (min-width: 720px) {
#advice-container {
display: flex;
width: 900px;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->
<title>Oshane| Advice generator app</title>
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/030a66e167.js" crossorigin="anonymous"></script>
</head>
<body>
<section id="advice-container">
<div id="static">
<h2>Click the Dice Button <br><br> below <br><br> to get advice</h2>
</div>
<div id="adviceNumber"> </div>
<div id="adviceResults"></div>
<div class="btn" id="getDataBtn">
<button id="spinDice" class="dice-container rotate" type="submit"><i class="fa-solid fa-dice-five"></i></button>
</div>
</section>
<section class="favouriteSection">
</section>
<!-- <script src="./node_modules/axios/dist/axios.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="app.js"></script>
</body>
</html>
]2]2how can I prevent this from adding the same text each time the add favourite icon is clicked? It should just add it once and if the add favourite btn is selected again and the quote already exists it should not repeat adding the same ones. I tried a few stuff but as I am a beginner those did not work.
Please anyone can assist?
You can check for something before adding/pushing into favorites array.
Check if something like id(best) or string exists in the arrray and if so - return, else push
Step by step, this is what you are missing:
Create an empty object.
Each time the user clicks the "Add to Favourites" button, you should check if it's already in that object.
If it is, you are done handling that click event.
If it is not, you should add it to the object and then proceed with the logic you currently have to update the UI.
Simplified example:
const rollButton = document.getElementById('roll');
const numberElement = document.getElementById('number');
const addToFavouritesButton = document.getElementById('addToFavourites');
const favouritesElement = document.getElementById('favourites');
let number = null;
rollButton.addEventListener('click', () => {
numberElement.textContent = number = Math.floor(Math.random() * 10);
addToFavouritesButton.removeAttribute('disabled');
});
const favourites = {};
addToFavouritesButton.addEventListener('click', () => {
if (favourites[number]) return;
favourites[number] = true;
favouritesElement.textContent = Object.keys(favourites).sort((a, b) => a - b).join(', ');
if (Object.keys(favourites).length === 10) {
numberElement.textContent = '🎉';
rollButton.setAttribute('disabled', true);
addToFavouritesButton.setAttribute('disabled', true);
}
});
body,
button {
font-family: monospace;
}
p {
text-align: center;
}
button {
border: 3px solid black;
border-radius: 4px;
background: transparent;
padding: 8px 16px;
}
button:hover {
background: yellow;
}
button:disabled {
border-color: #CCC;
color: #CCC;
background: transparent;
}
#number {
border: 3px solid black;
width: 48px;
height: 48px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
#favourites {
display: inline-flex;
align-items: center;
justify-content: center;
border: 3px solid black;
border-radius: 4px;
background: transparent;
padding: 8px 16px;
}
<p>
<button id="roll">🎲 Roll Dice</button>
<button id="addToFavourites" disabled>⭐ Add to Favourites</button>
</p>
<p>
<span id="number">?</span>
</p>
<p>
<span id="favourites"> </span>
</p>
I am creating a settings portion on a website. I want the features chosen to be "saved" and kept when the page refreshes. I attempted this but it seems to just reset the form when I refresh the page. Another issue is when I click on the cancel button, the toggle buttons reset but the dropdown comes back blank instead of going back to the placeholder "select timezone". The issue most likely lies in my javascript code below. It's also throwing an error in stack overflow but works properly on my website (minus the issues described above). Any suggestions would be much appreciated!
// ---------- TOGGLE BTN ----------
const toggle = document.getElementsByClassName("toggle");
const labels = document.getElementsByClassName("labels");
for(let i=0; i < 2; i++) {
labels[i].innerHTML = "OFF";
toggle[i].addEventListener( "click", () => {
if(labels[i].innerHTML == "OFF") {
// console.log("button toggled");
labels[i].classList.add("on");
labels[i].innerHTML= "ON";
} else {
labels[i].classList.remove("on");
labels[i].innerHTML = "OFF";
}
});
}
// ---------- LOCAL STORAGE DATA ----------
const save = document.getElementById("save");
const cancel = document.getElementById("cancel");
const emailBtn = document.getElementById("togBtn");
const publicBtn = document.getElementById("togBtn2");
const zone = document.getElementById("timezone");
// emailBtn.value = data;
// publicBtn.value = data;
// zone.value = data;
const data = {
email: emailBtn.value,
privacy: publicBtn.value,
timezone: zone.value
}
var emailVal = localStorage.getItem("email");
var privacyVal = localStorage.getItem("privacy");
var zoneVal = localStorage.getItem("timezone");
save.addEventListener('click', () => {
localStorage.setItem("email", emailBtn.value);
localStorage.setItem("privacy", publicBtn.value);
localStorage.setItem("timezone", zone.value);
});
cancel.addEventListener('click', () => {
localStorage.clear();
for(let i=0; i < 2; i++) {
labels[i].innerHTML = "OFF";
labels[i].classList.remove("on");
}
emailBtn.checked = false;
publicBtn.checked =false;
zone.value = 'Select Timezone';
});
.settings {
padding-left: 15px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.settings h3 {
flex-basis: 100%;
}
.button1,
.button2 {
flex-basis: 100%;
display: flex;
align-items:center;
}
label {
flex-basis: 90%;
}
input {
flex-basis: 10%;
}
.form-field {
flex-basis: 100%;
background-color: rgb(241, 240, 240);
border: 1px solid lightgrey;
color: grey;
border-radius: 5px;
padding: 10px;
margin: 0 15px 10px 0;
}
.settings-button {
display: flex;
justify-content: center;
}
button {
margin: 10px 15px 10px 0;
padding: 10px;
border: 1px solid lightgrey;
border-radius: 5px;
}
#save,
#cancel {
flex-basis: 50%;
}
#save {
background-color: #7477BF;
color: white;
}
#cancel {
background-color: darkgray;
color: white;
}
#timezone {
margin-top:25px;
}
/* toggle button */
.toggle {
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
position: relative;
outline: 0;
cursor: pointer;
margin: 10px 15px;
}
.toggle:after {
content: '';
width: 80px;
height: 28px;
display: inline-block;
background: rgba(196, 195, 195, 0.55);
border: 2px solid rgba(196, 195, 195, 0.55);
border-radius: 18px;
clear: both;
}
.toggle:before {
content: '';
width: 20px;
height: 20px;
display: block;
position: absolute;
top: 3px;
/* left: 0;
top: -3px; */
border: 2px solid rgba(196, 195, 195, 0.55);
border-radius: 50%;
background: rgb(255, 255, 255);
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6);
}
.toggle:checked:before {
left: 54px;
box-shadow: -1px 1px 3px rgba(0, 0, 0, 0.6);
}
.toggle:checked:after {
background: #7477BF;
}
.toggle,
.toggle:before,
.toggle:after,
.toggle:checked:before,
.toggle:checked:after {
transition: ease .4s;
-webkit-transition: ease .4s;
-moz-transition: ease .4s;
-o-transition: ease .4s;
}
.labels {
color: gray;
position: relative;
font-size: 15px;
transform: translate(-48px, -3px);
}
.on {
color: white;
transform: translate(-90px, -3px);
}
<section class="settings" id="settings">
<h3>Settings</h3>
<!-- custom CSS toggle code-->
<div class="button1">
<label for="togBtn">Send Email Notfications </label>
<input type="checkbox" class="toggle" id="togBtn">
<span class="labels"></span>
</div>
<div class="button2">
<label for="togBtn2">Set Profile to Public </label>
<input type="checkbox" class="toggle" id="togBtn2">
<span class="labels"></span>
</div>
<select class="form-field" id="timezone">
<option disabled selected>Select a Timezone</option>
<option>Eastern</option>
<option>Western</option>
<!-- more options -->
</select>
<div class="settings-button" >
<button class="button-primary" id="save">Save</button>
<button class="button-disabled" id="cancel">Cancel</button>
</div>
</section>
here a working example.
The problems with your code were that you were using emailBtn.value and publicBtn.value instead of emailBtn.checked and publicBtn.checked (they are checkbox so in order to get the correct value you have to read che checked property) and you were not loading the saved values on document load (the function inside window.addEventListener("load", ...) in my example.
Hope this helps you.
I made this iPhone in HTML (Please do not pay attention to the spaghetti code, and it's in german, if it is necessary i can translate it with pleasure):
var time = document.getElementById("time");
var notification = document.getElementById("notification");
var notificationHeader = document.getElementById("notificationHeader");
var notificationDescription = document.getElementById("notificationDescription");
var verificationCode = Math.floor(1000 + Math.random() * 9000);
var input = document.getElementById("instagramNumberText");
var correctOrWrongCheck = document.getElementById("correctOrWrongCheck");
var verificationCodePTag = document.getElementById("verificationCode");
var instagram = document.getElementById("instagramApp");
var mail = document.getElementById("mailApp");
var createAccountButton = document.getElementById("createAccount");
var createAccountForm = document.getElementById("createAccountForm");
var verificationCodeInstagramPage = document.getElementById("verificationCodeInstagramPage");
var controlVerificationCodeButton = document.getElementById("controlVerificationCode");
var continueToInstagramAccountButton = document.getElementById("continueToInstagramAccount");
var verificationCodeEmailDescription = document.getElementById("verificationCodeEmailDescription");
var verificationCodeEmail = document.getElementById("verificationCodeEmail");
var erfolgreichAngemeldet = document.getElementById("erfolgreichAngemeldet");
var instagramAccount = document.getElementById("instagramAccount");
var instagramName = document.getElementById("instagramName");
var instagramNameInput = document.getElementById("instagramNameInput");
// Time
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
// add a zero in front of numbers<10
m = checkTime(m);
document.getElementById('time').innerHTML = h + ":" + m;
t = setTimeout(function() {
startTime()
}, 500);
}
startTime();
// Insta
function controlVerificationCode() {
if (input.value == verificationCode) {
correctOrWrongCheck.innerHTML = "Der Code war korrekt!";
continueToInstagramAccountButton.style.display = "block";
continueToInstagramAccountButton.style.margin = "5px auto";
controlVerificationCodeButton.style.display = "none";
} else if (input.value !== verificationCode) {
correctOrWrongCheck.innerHTML = "Der Code ist leider Falsch!";
continueToInstagramAccountButton.style.display = "none";
controlVerificationCodeButton.style.display = "block";
}
}
verificationCodeEmailDescription.innerHTML = "Ihr Bestätigunscode lautet: " + verificationCode;
// OPEN AND CLOSE APPS
function openVerificationCodeInstagramPage() {
createAccountForm.style.display = "none";
verificationCodeInstagramPage.style.display = "block"
verificationCodeEmail.style.display = "block";
instagramName.value = instagramNameInput.value;
notification.style.transform = "translate(-50%, -50%) scale(0)";
notificationDescription.innerHTML = "Ihr Bestätigunscode lautet: ...";
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(1)";
}, 1000);
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}, 7000);
}
function continueToInstagramAccount() {
verificationCodeInstagramPage.style.display = "none";
instagramAccount.style.display = "flex";
erfolgreichAngemeldet.display = "none";
notificationDescription.innerHTML = "Erfolgreich bei Instagram angemeldet"
notification.style.transform = "translate(-50%, -50%) scale(0)";
erfolgreichAngemeldet.style.display = "block";
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(1)";
}, 1000);
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}, 7000);
var counter = 0;
var followers = document.getElementById('followers');
setTimeout(function(){
var st = setInterval(function(){
followers.innerHTML = ++counter;
},100)
},100);
}
function closeNotification() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}
function openInstagram() {
instagram.style.transform = "scale(1)";
}
function openMail() {
mail.style.transform = "scale(1)";
}
function closeApp() {
instagram.style.transform = "scale(0)";
mail.style.transform = "scale(0)";
}
window.onload = function() {
document.getElementById("instagramNumberText").value = '';
}
* {
margin: 0;
padding: 0;
font-family: 'Roboto',sans-serif;
user-select: none;
}
input:focus, textarea:focus {
outline: 0;
}
#phone {
height: 600px;
width: 350px;
border-radius: 50px;
position: absolute;
top: 600px;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border-top: 90px solid;
border-right: 15px solid;
border-left: 15px solid;
border-bottom: 90px solid;
background-image: url("https://ioshacker.com/wp-content/uploads/2019/06/iOS-13-wallpaper.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.app {
box-shadow: 0 0 9px -4px #000;
}
#topbar {
padding: 0.3em;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
height: 20px;
transform: translate(-4%,0) scale(0.9);
width: 370px;
}
#connection {
display: flex;
align-items: center;
width: 110px;
justify-content: space-around;
}
#battery {
display: flex;
align-items: center;
width: 110px;
justify-content: end;
}
#battery .bi-battery-full {
font-size: 23px;
margin-left: 5px;
}
#topbar .bi-wifi-2 {
font-size: 25px;
margin-top: -3px;
}
#time {
text-align: center;
}
#notification {
margin: 0;
position: absolute;
top: 365px;
left: 50%;
-ms-transform: translate(-50%, -50%) scale(0);
transform: translate(-50%, -50%) scale(0);
height: 85px;
width: 315px;
background: #EDEBED;
border-radius: 10px;
z-index: 10000;
transition: all 0.5s;
box-shadow: 0 0 10px -1px #525252;
padding: 0.5em 0 0.5em 1em;
display: flex;
flex-direction: column;
justify-content: center;
}
#notification h1 {
font-size: 23px;
}
#appsOne {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
#instagramIcon, #verificationCode, #mailIcon {
margin: 20px;
}
.app {
font-size: 40px;
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
transition: all 0.2s;
}
.app:hover {
cursor: pointer;
filter: brightness(90%);
}
.bi-instagram, .bi-envelope-fill {
width: 40px;
height: 40px;
color: #fff;
font-family: sans-serif;
}
/* Instagram */
#instagramIcon {
background: linear-gradient(45deg, #f09433 0%,#e6683c 25%,#dc2743 50%,#cc2366 75%,#bc1888 100%);
}
#instagramApp {
position: absolute;
top: 0;
left: 0;
background: #EAEAEA;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
transition: all 0.3s;
transform: scale(0);
z-index: 99999;
text-align: center;
}
.instagramHeader {
font-family: 'Handlee', cursive;
font-size: 35px;
}
.instagramSecondHeader {
font-size: 15px;
width: 260px;
margin: 1em 0;
}
#instagramNameInput, #instagramEmail, #instagramNumberText {
font-size: 15px;
padding: 0.5em;
border: 1px solid #D1D1D1;
margin: 0.5em 0 0.5em 0;
width: 220px;
}
.instagramButton {
width: 236px;
font-size: 15px;
padding: 0.5em;
background: #3296F0;
color: #fff;
border: none;
margin: 0.5em 0;
transition: all 0.2s;
}
.instagramButton:hover {
filter: brightness(80%);
cursor: pointer;
}
#verificationCodeInstagramPage {
display: none;
}
#continueToInstagramAccount {
display: none;
}
#instagramAccount {
display: none;
justify-content: flex-start;
height: 100%;
width: 100%;
background: #f7f7f7;
flex-direction: column;
align-items: center;
}
#instagramName {
font-size: 20px;
text-align: left;
width: 85%;
padding: 20px 20px 15px 10px;
border-bottom: 1px solid gray;
height: 20px;
border-right: none;
border-top: none;
border-left: none;
background: none;
}
#profilePicture {
font-size: 35px;
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
background: #eae9e9;
border-radius: 100000px;
margin: 20px;
border: 1px solid #6f6e6e;
color: #6f6e6e;
}
#instagramPictureAndNumbers {
display: inherit;
width: 360px;
}
#numbers {
width: 225px;
height: 45px;
margin: 35px 0 0 0;
}
#userDescription {
width: 320px;
font-size: 13px;
border: none;
background: none;
resize: none;
}
.bi-table {
font-size: 25px;
border-bottom: 1px solid;
width: 90%;
margin-top: 0.5em;
}
#emptyImages {
color: #c7c7c7;
margin: 100px;
font-size: 14px;
}
/* Mail */
#mailIcon {
background: linear-gradient(0deg, #05ffff 0%, #3cabe6 30%, #2763dc 70%);
}
#mailApp {
position: absolute;
top: 0;
left: 0;
background: #f6f6f6;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
transition: all 0.3s;
transform: scale(0);
z-index: 99999;
text-align: center;
}
#mailHeader {
font-size: 25px;
padding: 20px;
background: #fff;
width: 88%;
z-index: 999;
}
#verificationCodeEmail {
display: none;
}
.email {
background: #fff;
width: 97%;
padding: 5px;
border-top: 1px solid #e6e6e6;
}
.emailHeader {
text-align: left;
margin: 10px;
font-size: 25px;
}
#verificationCodeEmailDescription, #erfolgreichAngemeldetDescription {
text-align: left;
margin: 10px;
}
#erfolgreichAngemeldet {
display: none;
}
/* Home Button */
#homeButton {
position: absolute;
height: 60px;
width: 60px;
background: transparent;
z-index: 9999;
bottom: -107px;
border-radius: 100000px;
left: 50%;
-ms-transform: translate(-50%, -50%) rotate(-10deg);
transform: translate(-50%, -50%) rotate(-10deg);
border: 1px outset;
cursor: pointer;
}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.4.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#100;300;400&display=swap" rel="stylesheet">
<div id="notification" onclick="closeNotification();">
<h1 id="notificationHeader"><b>Neue Email erhalten!</b></h1>
<p id="notificationDescription"></p>
</div>
<div id="phone">
<div id="topbar">
<div id="connection">
<i class="bi bi-bar-chart-fill"></i>
LIDL LTE
<i class="bi bi-wifi-2"></i>
</div>
<p id="time"></p>
<div id="battery">
98%
<i class="bi bi-battery-full"></i>
</div>
</div>
<div id="slider">
<div id="appsOne">
<!-- Instagram -->
<div id="instagramIcon" class="app" onclick="openInstagram();"><i class="bi bi-instagram"></i></div>
<div id="instagramApp">
<form id="createAccountForm" action="#" onsubmit="openVerificationCodeInstagramPage(); return false;">
<h1 class="instagramHeader">Instagram</h1>
<p>Erstelle einen Account</p>
<input type="text" id="instagramNameInput" placeholder="Name" maxlength="12" autocomplete="off" required>
<input type="email" id="instagramEmail" placeholder="E-Mail" autocomplete="off" required>
<button type="submit" id="createAccount" class="instagramButton">Erstellen</button>
</form>
<div id="verificationCodeInstagramPage">
<h1 class="instagramHeader">Bestätigen</h1>
<p class="instagramSecondHeader">Wir haben ihn einen Bestätigungscode per Email gesendet!</p>
<input type="text" id="instagramNumberText" maxlength="4" onkeypress="return /[0-9]/i.test(event.key)" placeholder="Bestätigungscode"><br>
<button onclick="controlVerificationCode();" id="controlVerificationCode" class="instagramButton">Bestätigen</button>
<button class="instagramButton" id="continueToInstagramAccount" onclick="continueToInstagramAccount()">Weiter</button>
<p id="correctOrWrongCheck"></p>
</div>
<div id="instagramAccount">
<input type="text" id="instagramName">
<div id="instagramPictureAndNumbers">
<div id="profilePicture"><i class="bi bi-person-fill"></i></div>
<table id="numbers">
<tr>
<th id="posts">0</th>
<th id="followers">1</th>
<th id="following">0</th>
</tr>
<tr>
<td>Posts</td>
<td>Followers</td>
<td>Following</td>
</tr>
</table>
</div>
<textarea id="userDescription" placeholder="Beschreibung..." rows="10"></textarea>
<i class="bi bi-table"></i>
<p id="emptyImages">No images found</p>
</div>
</div>
<div id="appsTwo">
Second App Page
</div>
</div>
<!-- Mail App -->
<div id="mailIcon" class="app" onclick="openMail();"><i class="bi bi-envelope-fill"></i></div>
<div id="mailApp">
<h1 id="mailHeader">E-Mails</h1>
<div class="email" id="erfolgreichAngemeldet">
<h1 class="emailHeader">Instagram</h1>
<p class="emailDescription" id="erfolgreichAngemeldetDescription">Erfolgreich angemeldet</p>
</div>
<div class="email" id="verificationCodeEmail">
<h1 class="emailHeader">Instagram</h1>
<p class="emailDescription" id="verificationCodeEmailDescription">Ihr Bestätigunscode lautet</p>
</div>
</div>
</div>
<div id="homeButton" onclick="closeApp();"></div>
To see the iPhone better you should click on Full-Page in the snippet.
My problem was that I have 2 divs: #appsOne and #appsTwo which are in the div #slider. On the home page of the iPhone you can see two apps (#appsOne) and a text (#appsTwo) in the middle. The apps (#appsOne) should stay where they are but the text (#appsTwo) should be made on a second page with a horizontal scroll snap. How could I do that?
And here's an image, how it looks like without the slider and the #appsTwo div:
CSS Scroll-snapping
We can seperate the two 'screen's by wrapping each in a div with class panel.
To make the slider scrollable, we have to apply white-space: nowrap to force it into a single line. To make scroll-snap work horizontally, set scroll-snap-type to x and make it mandatory (scroll-snap-type: x mandatory;). This means that:
The visual viewport of this scroll container will rest on a snap point if it isn't currently scrolled. That means it snaps on that point when the scroll action finished, if possible. If content is added, moved, deleted or resized the scroll offset will be adjusted to maintain the resting on that snap point.MDN
We also set overscroll-behavior-x to contain which makes sure that no scroll chaining occurs to neighboring scrolling areas, e.g. underlying elements will not scroll.
We then apply scroll-snap-align: center to .panel. To prevent the overflowing contents in the panels, we also apply white-space: initial.
Result:
https://jsfiddle.net/Spectric/j7br8h5a/
JS Scroll-snapping (mouse drag)
We can take it one step further by adding support for user drag to scroll.
For this, we don't actually need scroll-snap at all. We can do it with pure JS.
Add an event listener for mousedown that sets isDown to true. Record the last position of the mouse.
Add an event listener for mousemove that checks whether the user is currently dragging (isDown == true). If the user is, calculate the distance from the current mouse position and the last mouse position, increment the slider's scrollLeft by the difference, and set the last position to the current position.
Add an event listener for mouseup that sets isDown to false and checks whether the slider's current scrollLeft is bigger than half. If it is, we can use scrollIntoView() on one panel to smoothly scroll it into the viewport.
To prevent scrolling when an app is opened, we can store the status in a variable which we set it to true when one of the open app function is called and false when the closeApp function is called. In the mousemove listener we also check whether this variable is true.
Best viewed in full-page mode
var time = document.getElementById("time");
var notification = document.getElementById("notification");
var notificationHeader = document.getElementById("notificationHeader");
var notificationDescription = document.getElementById("notificationDescription");
var verificationCode = Math.floor(1000 + Math.random() * 9000);
var input = document.getElementById("instagramNumberText");
var correctOrWrongCheck = document.getElementById("correctOrWrongCheck");
var verificationCodePTag = document.getElementById("verificationCode");
var instagram = document.getElementById("instagramApp");
var mail = document.getElementById("mailApp");
var createAccountButton = document.getElementById("createAccount");
var createAccountForm = document.getElementById("createAccountForm");
var verificationCodeInstagramPage = document.getElementById("verificationCodeInstagramPage");
var controlVerificationCodeButton = document.getElementById("controlVerificationCode");
var continueToInstagramAccountButton = document.getElementById("continueToInstagramAccount");
var verificationCodeEmailDescription = document.getElementById("verificationCodeEmailDescription");
var verificationCodeEmail = document.getElementById("verificationCodeEmail");
var erfolgreichAngemeldet = document.getElementById("erfolgreichAngemeldet");
var instagramAccount = document.getElementById("instagramAccount");
var instagramName = document.getElementById("instagramName");
var instagramNameInput = document.getElementById("instagramNameInput");
// Time
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
// add a zero in front of numbers<10
m = checkTime(m);
document.getElementById('time').innerHTML = h + ":" + m;
t = setTimeout(function() {
startTime()
}, 500);
}
startTime();
// Insta
function controlVerificationCode() {
if (input.value == verificationCode) {
correctOrWrongCheck.innerHTML = "Der Code war korrekt!";
continueToInstagramAccountButton.style.display = "block";
continueToInstagramAccountButton.style.margin = "5px auto";
controlVerificationCodeButton.style.display = "none";
} else if (input.value !== verificationCode) {
correctOrWrongCheck.innerHTML = "Der Code ist leider Falsch!";
continueToInstagramAccountButton.style.display = "none";
controlVerificationCodeButton.style.display = "block";
}
}
verificationCodeEmailDescription.innerHTML = "Ihr Bestätigunscode lautet: " + verificationCode;
// OPEN AND CLOSE APPS
function openVerificationCodeInstagramPage() {
createAccountForm.style.display = "none";
verificationCodeInstagramPage.style.display = "block"
verificationCodeEmail.style.display = "block";
instagramName.value = instagramNameInput.value;
notification.style.transform = "translate(-50%, -50%) scale(0)";
notificationDescription.innerHTML = "Ihr Bestätigunscode lautet: ...";
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(1)";
}, 1000);
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}, 7000);
}
function continueToInstagramAccount() {
verificationCodeInstagramPage.style.display = "none";
instagramAccount.style.display = "flex";
erfolgreichAngemeldet.display = "none";
notificationDescription.innerHTML = "Erfolgreich bei Instagram angemeldet"
notification.style.transform = "translate(-50%, -50%) scale(0)";
erfolgreichAngemeldet.style.display = "block";
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(1)";
}, 1000);
setTimeout(
function() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}, 7000);
var counter = 0;
var followers = document.getElementById('followers');
setTimeout(function() {
var st = setInterval(function() {
followers.innerHTML = ++counter;
}, 100)
}, 100);
}
function closeNotification() {
notification.style.transform = "translate(-50%, -50%) scale(0)";
}
var isAppOpened = false;
function openInstagram() {
isAppOpened = true;
instagram.style.transform = "scale(1)";
}
function openMail() {
isAppOpened = true;
mail.style.transform = "scale(1)";
}
function closeApp() {
isAppOpened = false;
instagram.style.transform = "scale(0)";
mail.style.transform = "scale(0)";
}
window.onload = function() {
document.getElementById("instagramNumberText").value = '';
}
const slider = document.getElementById("slider");
const panels = document.querySelectorAll('.panel');
var lastX = 0;
var isDown = false;
document.addEventListener("mousedown", function(e) {
lastX = e.pageX;
isDown = true;
})
document.addEventListener("mousemove", function(e) {
if (isDown && !isAppOpened) {
const curX = e.pageX;
const diff = lastX - curX;
slider.scrollLeft += diff;
lastX = curX;
}
})
document.addEventListener("mouseup", function() {
isDown = false;
slider.style.scrollBehavior = "smooth";
if (slider.scrollLeft > 175) {
panels[1].scrollIntoView();
} else {
panels[0].scrollIntoView();
}
slider.style.scrollBehavior = "unset";
})
* {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
user-select: none;
}
input:focus,
textarea:focus {
outline: 0;
}
#phone {
height: 600px;
width: 350px;
border-radius: 50px;
position: absolute;
top: 600px;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border-top: 90px solid;
border-right: 15px solid;
border-left: 15px solid;
border-bottom: 90px solid;
background-image: url("https://ioshacker.com/wp-content/uploads/2019/06/iOS-13-wallpaper.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.app {
box-shadow: 0 0 9px -4px #000;
}
#topbar {
padding: 0.3em;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
height: 20px;
transform: translate(-4%, 0) scale(0.9);
width: 370px;
}
#connection {
display: flex;
align-items: center;
width: 110px;
justify-content: space-around;
}
#battery {
display: flex;
align-items: center;
width: 110px;
justify-content: end;
}
#battery .bi-battery-full {
font-size: 23px;
margin-left: 5px;
}
#topbar .bi-wifi-2 {
font-size: 25px;
margin-top: -3px;
}
#time {
text-align: center;
}
#notification {
margin: 0;
position: absolute;
top: 365px;
left: 50%;
-ms-transform: translate(-50%, -50%) scale(0);
transform: translate(-50%, -50%) scale(0);
height: 85px;
width: 315px;
background: #EDEBED;
border-radius: 10px;
z-index: 10000;
transition: all 0.5s;
box-shadow: 0 0 10px -1px #525252;
padding: 0.5em 0 0.5em 1em;
display: flex;
flex-direction: column;
justify-content: center;
}
#notification h1 {
font-size: 23px;
}
#appsOne {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
#instagramIcon,
#verificationCode,
#mailIcon {
margin: 20px;
}
.app {
font-size: 40px;
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
transition: all 0.2s;
}
.app:hover {
cursor: pointer;
filter: brightness(90%);
}
.bi-instagram,
.bi-envelope-fill {
width: 40px;
height: 40px;
color: #fff;
font-family: sans-serif;
}
/* Instagram */
#instagramIcon {
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
}
#instagramApp {
position: absolute;
top: 0;
left: 0;
background: #EAEAEA;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
transition: all 0.3s;
transform: scale(0);
z-index: 99999;
text-align: center;
}
.instagramHeader {
font-family: 'Handlee', cursive;
font-size: 35px;
}
.instagramSecondHeader {
font-size: 15px;
width: 260px;
margin: 1em 0;
}
#instagramNameInput,
#instagramEmail,
#instagramNumberText {
font-size: 15px;
padding: 0.5em;
border: 1px solid #D1D1D1;
margin: 0.5em 0 0.5em 0;
width: 220px;
}
.instagramButton {
width: 236px;
font-size: 15px;
padding: 0.5em;
background: #3296F0;
color: #fff;
border: none;
margin: 0.5em 0;
transition: all 0.2s;
}
.instagramButton:hover {
filter: brightness(80%);
cursor: pointer;
}
#verificationCodeInstagramPage {
display: none;
}
#continueToInstagramAccount {
display: none;
}
#instagramAccount {
display: none;
justify-content: flex-start;
height: 100%;
width: 100%;
background: #f7f7f7;
flex-direction: column;
align-items: center;
}
#instagramName {
font-size: 20px;
text-align: left;
width: 85%;
padding: 20px 20px 15px 10px;
border-bottom: 1px solid gray;
height: 20px;
border-right: none;
border-top: none;
border-left: none;
background: none;
}
#profilePicture {
font-size: 35px;
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
background: #eae9e9;
border-radius: 100000px;
margin: 20px;
border: 1px solid #6f6e6e;
color: #6f6e6e;
}
#instagramPictureAndNumbers {
display: inherit;
width: 360px;
}
#numbers {
width: 225px;
height: 45px;
margin: 35px 0 0 0;
}
#userDescription {
width: 320px;
font-size: 13px;
border: none;
background: none;
resize: none;
}
.bi-table {
font-size: 25px;
border-bottom: 1px solid;
width: 90%;
margin-top: 0.5em;
}
#emptyImages {
color: #c7c7c7;
margin: 100px;
font-size: 14px;
}
/* Mail */
#mailIcon {
background: linear-gradient(0deg, #05ffff 0%, #3cabe6 30%, #2763dc 70%);
}
#mailApp {
position: absolute;
top: 0;
left: 0;
background: #f6f6f6;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
transition: all 0.3s;
transform: scale(0);
z-index: 99999;
text-align: center;
}
#mailHeader {
font-size: 25px;
padding: 20px;
background: #fff;
width: 88%;
z-index: 999;
}
#verificationCodeEmail {
display: none;
}
.email {
background: #fff;
width: 97%;
padding: 5px;
border-top: 1px solid #e6e6e6;
}
.emailHeader {
text-align: left;
margin: 10px;
font-size: 25px;
}
#verificationCodeEmailDescription,
#erfolgreichAngemeldetDescription {
text-align: left;
margin: 10px;
}
#erfolgreichAngemeldet {
display: none;
}
/* Home Button */
#homeButton {
position: absolute;
height: 60px;
width: 60px;
background: transparent;
z-index: 9999;
bottom: -107px;
border-radius: 100000px;
left: 50%;
-ms-transform: translate(-50%, -50%) rotate(-10deg);
transform: translate(-50%, -50%) rotate(-10deg);
border: 1px outset;
cursor: pointer;
}
#slider {
white-space: nowrap;
position: relative;
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
height: calc(100% - 30px);
}
.panel {
display: inline-block;
width: 350px;
white-space: initial;
}
#appsTwo {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.4.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#100;300;400&display=swap" rel="stylesheet">
</head>
<body>
<div id="notification" onclick="closeNotification();">
<h1 id="notificationHeader"><b>Neue Email erhalten!</b></h1>
<p id="notificationDescription"></p>
</div>
<div id="phone">
<div id="topbar">
<div id="connection">
<i class="bi bi-bar-chart-fill"></i> LIDL LTE
<i class="bi bi-wifi-2"></i>
</div>
<p id="time"></p>
<div id="battery">
98%
<i class="bi bi-battery-full"></i>
</div>
</div>
<div id="slider">
<div class="panel">
<div id="appsOne">
<!-- Instagram -->
<div id="instagramIcon" class="app" onclick="openInstagram();"><i class="bi bi-instagram"></i></div>
<div id="instagramApp">
<form id="createAccountForm" action="#" onsubmit="openVerificationCodeInstagramPage(); return false;">
<h1 class="instagramHeader">Instagram</h1>
<p>Erstelle einen Account</p>
<input type="text" id="instagramNameInput" placeholder="Name" maxlength="12" autocomplete="off" required>
<input type="email" id="instagramEmail" placeholder="E-Mail" autocomplete="off" required>
<button type="submit" id="createAccount" class="instagramButton">Erstellen</button>
</form>
<div id="verificationCodeInstagramPage">
<h1 class="instagramHeader">Bestätigen</h1>
<p class="instagramSecondHeader">Wir haben ihn einen Bestätigungscode per Email gesendet!
</p>
<input type="text" id="instagramNumberText" maxlength="4" onkeypress="return /[0-9]/i.test(event.key)" placeholder="Bestätigungscode"><br>
<button onclick="controlVerificationCode();" id="controlVerificationCode" class="instagramButton">Bestätigen</button>
<button class="instagramButton" id="continueToInstagramAccount" onclick="continueToInstagramAccount()">Weiter</button>
<p id="correctOrWrongCheck"></p>
</div>
<div id="instagramAccount">
<input type="text" id="instagramName">
<div id="instagramPictureAndNumbers">
<div id="profilePicture"><i class="bi bi-person-fill"></i></div>
<table id="numbers">
<tr>
<th id="posts">0</th>
<th id="followers">1</th>
<th id="following">0</th>
</tr>
<tr>
<td>Posts</td>
<td>Followers</td>
<td>Following</td>
</tr>
</table>
</div>
<textarea id="userDescription" placeholder="Beschreibung..." rows="10"></textarea>
<i class="bi bi-table"></i>
<p id="emptyImages">No images found</p>
</div>
</div>
<div id="mailIcon" class="app" onclick="openMail();"><i class="bi bi-envelope-fill"></i></div>
<div id="mailApp">
<h1 id="mailHeader">E-Mails</h1>
<div class="email" id="erfolgreichAngemeldet">
<h1 class="emailHeader">Instagram</h1>
<p class="emailDescription" id="erfolgreichAngemeldetDescription">Erfolgreich angemeldet</p>
</div>
<div class="email" id="verificationCodeEmail">
<h1 class="emailHeader">Instagram</h1>
<p class="emailDescription" id="verificationCodeEmailDescription">Ihr Bestätigunscode lautet
</p>
</div>
</div>
</div>
</div>
<div class="panel">
<div id="appsTwo">
<div>
Second App Page
</div>
</div>
</div>
</div>
<div id="homeButton" onclick="closeApp();"></div>
</div>
</body>
</html>
Result:
You can hide the horizontal scrollbar by applying overflow-x:hidden to #slider
I'm trying to create a project card with user info when the user clicks on a button. When the user clicks the new project button, a modal form pops up that takes the user info and has a create button. The program should add a new project card whenever the user clicks the create button. To achieve this I added a click event listener to the Add new project button and another to Create button. I nested the create event listener inside the add new project event listener.
Here's the event listener.
addTileBtn.addEventListener("click", (e) => {
e.preventDefault();
modal.style.display = "block";
const titleField = document.querySelector("#title");
const descriptionField = document.querySelector("#description");
const create = document.querySelector("#create");
const close = document.querySelector("#close");
create.addEventListener("click", (e) => {
e.preventDefault();
title = titleField.value;
description = descriptionField.value;
function createProjectTile() {
const projectTile = document.createElement("div");
projectTile.classList.add("cards-grid__tile");
projectTile.textContent = title;
console.log(title, description);
return projectTile;
}
cardsGrid.appendChild(createProjectTile());
modal.style.display = "none";
});
close.addEventListener("click", (e) => {
e.preventDefault();
modal.style.display = "none";
});
});
The problem is that when I create the first card it works fine. But the second time, it creates two cards and 3 cards on the 3rd time and so on.
Here is the JSFiddle link for the full code.
I've edited your code, this should be what you wanted:
const logoutBtn = document.querySelector("#logout");
const addTileBtn = document.querySelector("#add-tile");
const cardsGrid = document.querySelector(".cards-grid");
const modal = document.querySelector(".modal");
const titleField = document.querySelector("#title");
const descriptionField = document.querySelector("#description");
const create = document.querySelector("#create");
const close = document.querySelector("#close");
addTileBtn.addEventListener("click", (e) => {
e.preventDefault();
modal.style.display = "block";
titleField.value = "";
descriptionField.value = "";
});
create.addEventListener("click", (e) => {
e.preventDefault();
title = titleField.value;
description = descriptionField.value;
function createProjectTile() {
const projectTile = document.createElement("div");
projectTile.classList.add("cards-grid__tile");
projectTile.textContent = title;
console.log(title, description);
return projectTile;
}
cardsGrid.appendChild(createProjectTile());
modal.style.display = "none";
});
close.addEventListener("click", (e) => {
e.preventDefault();
modal.style.display = "none";
});
:root {
--main-red: #be3144;
--main-white: #f0f0f0;
--main-gray: #303841;
--main-blue: #45567d;
--main-blue3: #1c262f;
--main-blue2: #27333d;
--main-blue1: #2e3d49;
--main-light-blue: #02b3e4;
--main-black: #000000;
--main-light-black: #3a3d40;
--main-dark-black: #181719;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
img {
display: block;
max-width: 100%;
height: auto;
}
body {
font-family: "Poppins", sans-serif;
font-size: 1.8rem;
font-weight: 400;
line-height: 1.4;
color: var(--main-white);
}
h1,
h2 {
font-family: "Raleway", sans-serif;
font-weight: 700;
text-align: center;
}
h1 {
font-size: 3.5rem;
}
h2 {
font-size: 2rem;
color: var(--main-blue);
display: block;
}
p {
font-size: 1.8rem;
font-weight: 200;
font-style: italic;
color: var(--main-white);
}
a {
text-decoration: none;
text-align: center;
display: block;
}
.main {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100vh;
background-color: var(--main-white);
}
.box {
border: none;
box-shadow: 0 2px 4px rgb(0 0 0 / 10%), 0 8px 16px rgb(0 0 0 / 10%);
border-radius: 8px;
background-color: #fff;
}
.box__fields {
padding: 20px;
}
.box-field {
margin-bottom: 20px;
display: flex;
justify-content: center;
}
.icon {
position: absolute;
padding: 10px;
color: gray;
min-width: 50px;
text-align: center;
font-size: 20px;
top: 50%;
transform: translateY(-50%);
}
input,
textarea {
font-size: 17px;
padding: 14px 16px;
width: 300px;
cursor: text;
border: 1px solid var(--main-gray);
border-radius: 6px;
outline: none;
padding-left: 45px;
}
.box-btn {
border: none;
border-radius: 6px;
font-size: 20px;
line-height: 48px;
padding: 0 16px;
}
.app,
.main-content {
height: 100%;
}
.title-area {
background-color: var(--main-blue3);
width: 100%;
font-size: 18px;
min-height: 60px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
}
.title-area__item {
padding: 10px 30px;
}
.logout-btn {
border: none;
border-radius: 6px;
font-size: 20px;
line-height: 30px;
padding: 0 16px;
width: 100px;
cursor: pointer;
color: #fff;
background-color: var(--main-light-blue);
}
.logout-btn:hover {
background-color: #029be4;
}
.content-area {
margin-top: 60px;
width: 100%;
height: 100%;
overflow: auto;
background-color: var(--main-blue);
}
.cards-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 50px;
margin-bottom: 3rem;
padding: 5rem 3rem;
}
.cards-grid__tile {
background-color: var(--main-blue2);
max-width: 200px;
padding: 30px;
text-align: center;
font-size: 1.2rem;
}
.add-tile-btn {
border: none;
border-radius: 6px;
font-size: 15px;
line-height: 48px;
padding: 0 10px;
cursor: pointer;
color: #fff;
background-color: var(--main-light-blue);
}
.modal {
display: none;
width: 350px;
font-size: 1.2rem;
position: relative;
top: 10%;
left: 50%;
transform: translateX(-50%);
overflow: visible;
}
.box {
background-color: var(--main-blue1);
opacity: 0.95;
}
.box-field {
flex-direction: column;
}
input,
textarea {
padding: 5px 10px;
resize: none;
}
.wrapper {
position: relative;
text-align: center;
}
.create-btn {
width: 100px;
cursor: pointer;
color: #fff;
background-color: var(--main-light-blue);
}
.close {
cursor: pointer;
position: absolute;
top: 20px;
left: 290px;
}
#modal-form {
position: absolute;
}
.icon {
color: var(--main-blue3);
}
<div class="app">
<div class="nav-wrapper">
<nav id="nav" class="nav"></nav>
</div>
<div class="main-content">
<div class="title-area">
<div class="title-area__item">Menu</div>
<div class="title-area__item">Boards</div>
<div class="title-area__item">
<button id="logout" class="logout-btn btn">
Logout
</button>
</div>
</div>
<div class="content-area">
<div class="modal">
<form id="modal-form" class="box">
<a id="close" class="close">
<i class="fa fa-times icon">close</i>
</a>
<div class="box__fields">
<div class="box-field">
<label for="title"> Title </label>
<input
id="title"
type="text"
name="title"
required
autofocus
/>
</div>
<div class="box-field">
<label for="description">
Description
</label>
<textarea
id="description"
name="title"
rows="6"
cols="40"
></textarea>
</div>
<div class="box-field">
<div class="wrapper">
<button
id="create"
class="create-btn box-btn btn"
>
Create
</button>
</div>
</div>
</div>
</form>
</div>
<div class="cards-grid">
<div class="cards-grid__tile">
<button id="add-tile" class="add-tile-btn btn">
+ Add new project
</button>
</div>
</div>
</div>
</div>
</div>
window.addEventListener for scroll event is not working in my JS. I've tried several ways but still not working. I've used intersectionObserver in the JS also. Here is the JS code
const moveToAbout = () => {
document.getElementById('about').scrollIntoView(true)
}
const moveToWork = () => {
document.getElementById('work').scrollIntoView()
}
const moveToTop = () => {
document.getElementById('main-section').scrollIntoView(true)
}
const options = {
root: null,
threshold: 0,
rootMargin: "-150px"
}
const header = document.querySelector("header")
const sections = document.querySelectorAll(".section")
const mainSection = document.querySelector(".main-container")
const bttWrapper = document.getElementById('bttBtn-wrapper')
const veganImage = document.getElementById('vegan-store-image')
const navbar = document.getElementById('header')
veganImage.onclick = () => {
window.open("https://thoughtlessmind.github.io/Vegan-store")
}
const sectionOne = document.querySelector(".about-section");
// bttWrapper.style.display = 'none'
const mainObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
header.classList.remove("nav-theme-2")
bttWrapper.classList.add("btnWrapperHidden")
bttWrapper.classList.remove("btnWrapperShow")
} else {
header.classList.add("nav-theme-2")
bttWrapper.classList.add("btnWrapperShow")
}
// console.log(entry.target, '-', entry.isIntersecting)
});
}, options);
mainObserver.observe(mainSection)
window.addEventListener("scroll", (event)=>{
console.log("scrolled")
var scroll = this.scrollY
if(scroll > 20){
console.log('reached')
}
})
const test = () =>{
console.log('working')
}
window.addEventListener("scroll", test)
window.addEventListener("scroll", () => console.log(window.pageYOffset));
Later in the lower part, I've tried to add scroll event in some ways but nothing is happening.
Here is the link for the whole repo: Github repo link
remove height property from CSS main. It is working now :
use min-height, max-height
const moveToAbout = () => {
document.getElementById('about').scrollIntoView(true)
}
const moveToWork = () => {
document.getElementById('work').scrollIntoView()
}
const moveToTop = () => {
document.getElementById('main-section').scrollIntoView(true)
}
const options = {
root: null,
threshold: 0,
rootMargin: "-150px"
}
const header = document.querySelector("header")
const sections = document.querySelectorAll(".section")
const mainSection = document.querySelector(".main-container")
const bttWrapper = document.getElementById('bttBtn-wrapper')
const veganImage = document.getElementById('vegan-store-image')
const navbar = document.getElementById('header')
veganImage.onclick = () => {
window.open("https://thoughtlessmind.github.io/Vegan-store")
}
const sectionOne = document.querySelector(".about-section");
// bttWrapper.style.display = 'none'
const mainObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
header.classList.remove("nav-theme-2")
bttWrapper.classList.add("btnWrapperHidden")
bttWrapper.classList.remove("btnWrapperShow")
} else {
header.classList.add("nav-theme-2")
bttWrapper.classList.add("btnWrapperShow")
}
// console.log(entry.target, '-', entry.isIntersecting)
});
}, options);
mainObserver.observe(mainSection)
window.onload = () =>{
console.log("loaded");
window.onscroll = function()
{
console.log("scrolling.....", window.scrollY);
}
}
#import 'global.css';
/* -----Navigation bar styles */
#import 'navbar.css';
/* ----------- Main contaier styles*/
main{
overflow: scroll;
scroll-snap-type: y mandatory;
}
.section{
/* scroll-snap-align: start; */
/* Uncomment above to add snap scrolling effect */
margin-left: auto;
margin-right: auto;
width: 80%;
max-width: 1100px;
border-bottom: 1px solid grey;
}
.main-container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
}
.name-text{
font-size: 2.8rem;
font-weight: 500;
color: var(--primary-text-color);
}
.intro-text{
padding: 1rem;
padding-left: 0;
font-size: 1.2rem;
color: var(--para-text-color);
}
.right-container{
text-align: left;
}
.text-container{
align-self: center;
}
.left-image{
width: 200px;
height: 200px;
background-color: palegreen;
animation: rotate 8s infinite ease-in-out ;
}
#keyframes rotate{
0%{
border-radius: 0;
}
50%{
border-radius: 50%;
transform: rotate(145deg);
background-color: green;
}
100%{
transform: rotate(360deg);
border-radius: 0;
}
}
.social-link-container{
margin-top: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.social-logo{
font-size: 2rem;
color: var(--primary-text-color);
}
.social-link{
margin: 0 10px;
}
/* About section */
.about-section{
height: 100vh;
padding-top: 38.5px;
border-bottom: 1px solid grey;
}
.about-section > h2{
padding: 10px 10px 10px 0px;
}
/* ----Work section ---- */
#work{
height: 100vh;
padding-top: 38.5px;
}
#work >h2 {
padding: 10px 10px 10px 0;
}
/* .inverse{
background-color: #111;
color: #eee;
} */
.project-card{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10px;
border-radius: 5px;
margin-top: 15px;
transition: 0.3s;
}
.project-card:hover{
background-color: rgba(200, 200, 200, 0.2);
}
.left-side-card{
padding-right: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
max-height: 145px;
height: 145px;
}
.project-name{
margin-bottom: 10px;
display: inline-block;
}
.project-link{
text-decoration: none;
letter-spacing: 0.8px;
position: relative;
}
.project-name::after{
position: absolute;
bottom: 0;
left: 0;
content: '';
height: 1px;
width: 100%;
background-color: black;
/* transform: scale(1); */
transition: 0.3s;
transform-origin: left;
}
.project-name:hover::after{
transform: scale(0);
transform-origin: left;
}
.project-description {
word-spacing: 0.8px;
letter-spacing: -0.2px;
}
.project-image{
height: 150px;
width: 250px;
cursor: pointer;
border-radius: 5px;
}
.tech-stack-container{
display: flex;
}
.tech-stack{
margin-right: 10px;
font-size: 12px;
font-weight: 600;
color: rgba(198, 198, 198,0.8);
transition: 0.3s;
}
.project-card:hover .tech-stack{
color: #6d6d6d
}
.repo-link{
margin-left: 20px;
}
.repo-logo{
color: rgba(0, 0, 0, 0.8);
}
.repo-logo:hover{
color: rgba(0, 0, 0, 0.6);
}
#media only screen and (max-width: 500px){
nav{
display: flex;
align-items: center;
justify-content: center;
float: none;
height: 22px;
}
.section{
width: 90%;
}
.main-container{
flex-direction: column-reverse;
justify-content: space-evenly;
}
.name-text{
text-align: center;
font-size: 28px;
}
.intro-text{
font-size: 18px;
}
.project-card{
flex-direction: column;
}
#work{
min-height: fit-content;
height: fit-content;
}
}
header {
position: fixed;
width: 100%;
background: rgba(255, 255, 255, 0.8);
padding: 10px 0;
z-index: 1;
transition: all ease-in-out 0.5s;
}
.green-nav {
background-color: lawngreen;
}
header:after {
content: "";
display: block;
clear: both;
}
nav {
float: right;
padding: 0 10%;
}
nav a {
font-size: 1rem;
margin: 5px 10px;
color: #484848;
text-decoration: none;
transition: 0.3s;
padding-bottom: 2px;
font-weight: 500;
position: relative;
padding: 2px 5px;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
}
nav a::after {
position: absolute;
bottom: 0;
left: 0;
content: '';
height: 1px;
width: 100%;
background-color: #484848;
transform: scaleX(0);
transition: 0.5s;
transform-origin: center;
}
nav a:hover::after {
transform: scaleX(1);
}
* {
margin: 0;
padding: 0;
scroll-behavior: smooth;
}
:root{
--primary-text-color: #000;
--para-text-color: #323232;
}
body {
font-family: 'Montserrat', sans-serif;
font-weight: 400;
/* scrollbar-color: rgba(0, 0, 0, .5);
scrollbar-track-color: #f1f1f1; */
}
a {
text-decoration: none;
color: #000;
}
/*-------- Custom scroll bar and selection -----*/
#media only screen and (min-width: 600px) {
::-webkit-scrollbar {
width: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(0, 0, 0, .5);
box-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, .6);
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
}
::selection {
background-color: rgb(78, 81, 83);
color: #fff;
}
/* ------- back to top btn */
#bttBtn-wrapper {
position: absolute;
bottom: 50px;
right: 50px;
background-color: grey;
border-radius: 50%;
height: 40px;
width: 40px;
cursor: pointer;
}
.btnWrapperHidden {
transform: scale(0);
transform-origin: center;
transition: 300ms;
}
.btnWrapperShow {
transform: scale(1) rotate(360deg);
transform-origin: center;
transition: 300ms;
}
#bttBtn {
width: 15px;
height: 15px;
border-radius: 2dpx;
border-left: 3px solid;
border-top: 3px solid;
transform: rotate(45deg);
margin: auto;
margin-top: 11px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="google-site-verification" content="x2GVvk7gy3nGrRmARofMXwMNs9MIXvu2BcyEs7RH8KQ" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500,700&display=swap" rel="stylesheet">
<meta name="Description" content="Name: Rajiv, thoughtlessmind, Profession: Web developer, Country: India, ">
<script src="https://kit.fontawesome.com/09ef7cae5b.js" crossorigin="anonymous"></script>
<script defer src="index.js"></script>
<link rel="stylesheet" href="CSS/style.css">
<!-- Chrome, Firefox OS and Opera -->
<meta name="theme-color" content="#4285f4">
<!-- Windows Phone -->
<meta name="msapplication-navbutton-color" content="#4285f4">
<!-- iOS Safari -->
<meta name="apple-mobile-web-app-status-bar-style" content="#4285f4">
<title>Rajiv</title>
</head>
<body>
<div id="top"></div>
<header>
<nav>
<a onclick="moveToWork()">Work</a>
<a onclick="moveToAbout()">About</a>
<a onclick="moveToContact()">Contact</a>
</nav>
</header>
<main>
<div class="main-container section" id="main-section">
<!-- <img src="" alt="avatar" class="avatar" style="height: 200px;width: 200px; background-color: wheat;align-self: center;"> -->
<div class="right-container">
<div class="text-container">
<h1 class="name-text">Rajiv</h1>
<p class="intro-text">
Hey, I'm a web developer based in New Delhi.
<br>
I build things using <b>Javasript</b>.
</p>
</div>
</div>
<div class="left-container">
<div class="left-image">
</div>
<div class="social-link-container">
<a href="https://github.com/thoughtlessmind" target="_blank" id="github" class="social-link">
<i class="fab fa-github social-logo"></i>
</a>
<a href="https://www.linkedin.com/in/thoughtlessmind/" target="_blank" id="linkedin"
class="social-link">
<i class="fab fa-linkedin social-logo"></i>
</svg>
</a>
</div>
</div>
</div>
<!-- Work Section -->
<div id="work" class="work-section section">
<h2>Work</h2>
<div class="project-card">
<div class="left-side-card">
<div>
<a href="https://thoughtlessmind.github.io/Vegan-store" target="_blank" class="project-link">
<h3 class="project-name">
Vegan Store
</h3>
</a>
<p class="project-description">
It is a dummy vegan food store website. <br>
This is a fully responsive website made using CSS Flexbox and Grids
</p>
</div>
<div title="techstack used" class="tech-stack-container">
<p class="tech-stack html-logo">HTML</p>
<p class="tech-stack css-logo">CSS</p>
<a title="open repo" href="" class="repo-link">
<i class="fas fa-code repo-logo"></i>
</a>
</div>
</div>
<div class="right-side-card">
<img src="/assets/vegan-store-img.jpg" title="Visit Page" alt="Vegan store" class="project-image"
id="vegan-store-image">
</div>
</div>
<div class="project-card">
<div class="left-side-card">
<div>
<a href="https://thoughtlessmind.github.io/Vegan-store" target="_blank" class="project-link">
<h3 class="project-name">
Vegan Store
</h3>
</a>
<p class="project-description">
It is a dummy vegan food store website. <br>
This is a fully responsive website made using CSS Flexbox and Grids
</p>
</div>
<div title="techstack used" class="tech-stack-container">
<p class="tech-stack html-logo">HTML</p>
<p class="tech-stack css-logo">CSS</p>
<a title="open repo" href="" class="repo-link">
<i class="fas fa-code repo-logo"></i>
</a>
</div>
</div>
<div class="right-side-card">
<img src="/assets/vegan-store-img.jpg" title="Visit Page" alt="Vegan store" class="project-image"
id="vegan-store-image">
</div>
</div>
</div>
<!-- about section -->
<div id="about" class="about-section section">
<h2>About</h2>
<div class="education-container">
<h3>Education</h3>
</div>
</div>
<!-- Back to top btn -->
<div onclick="moveToTop()" id="bttBtn-wrapper">
<div id="bttBtn">
</div>
</div>
</main>
</body>
</html>
Try this one
const main = document.querySelector('main');
// main.onscroll = logScroll;
main.addEventListener('scroll', logScroll)
function logScroll(e) {
console.log(`Scroll position: ${e.target.scrollTop}`);
if(e.target.scrollTop == 761){
console.log('About Page is Reached');
}
}
Note for target.onscroll
Only one onscroll handler can be assigned to an object at a time. For greater flexibility, you can pass a scroll event to the EventTarget.addEventListener() method instead.
As explained here https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onscroll
As I understand here in my code above, the target.scrollTop will only works when you have selected a valid target in your document object. In this case as I inspect your html markup you have wrapped your whole sections to a main tag.
Now that's it, I tried to get your main tag and add an eventListener to it, and it works to me. Hope this also works to you.