I want to change the words to icons in the exchange rate, I mean, so that it is not 1 USD = 36.5686 UAH, but 1 $ = 36.5686 ₴ and so on. I tried to put custom-select__option-symbol instead of custom-select__option-name, but it either doesn't work or takes only the first two currency icons and doesn't change them when changing currencies
/*******************************************************************************
* Initialize the amount for the first currency
*******************************************************************************/
function initializeAmount() {
document.getElementById('amount-one').addEventListener('input', refreshAmount);
}
/*******************************************************************************
* Initialize the Swap trigger already existing in DOM
*******************************************************************************/
function initializeSwap() {
swap.addEventListener('click', () => {
const [selectOne, selectTwo] = document.querySelectorAll('.custom-select');
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const [valueOne, valueTwo] = [selectOne, selectTwo].map(
select => select.querySelector('.custom-select__option--select').dataset.value
);
//--------------------------------------------------------------------------
// Dirty trick to avoid problems when swapping currencies on the 2 DDs
// by finding the currencies not chosen by the two dropdowns
// and first selecting a third currency on the first dropdown
// before doing the actual swap
//--------------------------------------------------------------------------
const availableCurrencies = [];
const chosenCurrencies = [valueOne, valueTwo];
selectOne.querySelectorAll('.custom-select__list .custom-select__option-name').forEach((option)=>{
availableCurrencies.push( option.innerText );
});
const notChosenCurrencies = availableCurrencies.filter(chosen => !chosenCurrencies.includes(chosen));
amountOne.value = amountTwo.value
selectOne.querySelector(`[data-value="${notChosenCurrencies[0]}"]`).click();
selectTwo.querySelector(`[data-value="${valueOne}"]`).click();
selectOne.querySelector(`[data-value="${valueTwo}"]`).click();
refreshConversionRatesAndAmount();
});
}
/*******************************************************************************
* Initialize the Currency Dropdowns already defined in the DOM
*******************************************************************************/
function initializeCurrencyDropdowns() {
//given the array of all .custom-select
[...document.querySelectorAll(".custom-select")]
//map()
.map(select => {
//inits dropdown options
let selected = select.querySelector(".custom-select__option--select");
if (selected) {
select.dataset.value = selected.dataset.value;
const placeholder = select.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
}
//adds click event listener to the list of options
select.querySelector(".custom-select__list").addEventListener("click", e => {
//--------------------------------------------------------------------------
// Logic to hide from the other DD the selected currency in this DD
//--------------------------------------------------------------------------
//fetches information about the currently selected dropdown
const thisDD = e.target.closest('.custom-select');
const currencyCurrentlySelected = e.target.closest('.custom-select__option').dataset.value;
//fetches information about the other dropdown
const otherDD_id = ((thisDD.id == 'curr-one' ? 'curr-two' : 'curr-one'));
const otherDD = document.getElementById(otherDD_id);
//removes the displaynone class to all the options in the other dropdown
otherDD.querySelectorAll('.custom-select__option').forEach((option)=>{
option.classList.remove('display-none');
});
//adds the class displaynone to the currently selected currency in the second dropdown
otherDD.querySelector(`.custom-select__option[data-value="${currencyCurrentlySelected}"]`)
.classList.add('display-none');
//--------------------------------------------------------------------------
let target = e.target.closest(".custom-select__option");
if (target) {
let parent = target.closest(".custom-select");
parent
.querySelector(".custom-select__option--select")
.classList.remove("custom-select__option--select");
target.classList.add("custom-select__option--select");
let selected = parent.querySelector(".custom-select__option--select");
parent.dataset.value = selected.dataset.value;
const placeholder = parent.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
target.closest(".custom-select").classList.remove("custom-select--drop");
}
//--------------------------------------------------------------------------
refreshConversionRatesAndAmount();
});
//adds click event listener to the placeholder
select.querySelector(".custom-select__placeholder").addEventListener("click", e => {
let target = e.target.closest(".custom-select__placeholder");
if (target) {
target.closest(".custom-select").classList.toggle("custom-select--drop");
}
});
});
}
/*******************************************************************************
* Refresh the conversion rates and converted amount (and metadata)
* displayed in the respective labels
*******************************************************************************/
async function refreshConversionRatesAndAmount() {
const rates = await fetchConversionRates();
const currencyOne = getSelectedCurrencyOne();
const currencyTwo = getSelectedCurrencyTwo();
const rateOne = rates[currencyOne];
const rateTwo = rates[currencyTwo];
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const rateLabel = document.getElementById('rate');
const ratio = (1 * rateOne.rate / rateTwo.rate).toFixed(4);
rateLabel.innerText = `1 ${currencyOne} = ${ratio} ${currencyTwo}`;
amountTwo.ratio = ratio;
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Refresh the amount only
*******************************************************************************/
function refreshAmount() {
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Fetch and return the conversion rates from a static url
*******************************************************************************/
async function fetchConversionRates() {
const url = 'https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json';
const response = await fetch(url);
const data = await response.json();
data.unshift({
"txt": "Українська гривня",
"rate": 1,
"cc": "UAH"
});
const ratesMapped = Object.assign({}, ...data.map((rate) => ({[rate.cc]: rate})));
return ratesMapped;
}
/*******************************************************************************
* Returns the Currency code selected on the first currency dropdown
*******************************************************************************/
function getSelectedCurrencyOne() {
const curr_oneDD = document.querySelector('#curr-one.custom-select');
return curr_oneDD.textContent.trim().slice(0, 3);
}
/*******************************************************************************
* Returns the Currency code selected on the second currency dropdown
*******************************************************************************/
function getSelectedCurrencyTwo() {
const curr_twoDD = document.querySelector('#curr-two.custom-select');
return curr_twoDD.textContent.trim().slice(0, 3);
}
initializeAmount();
initializeSwap();
initializeCurrencyDropdowns();
refreshConversionRatesAndAmount();
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 100vh;
margin: 0;
}
.custom-select {
display: block;
width: 150px;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 1;
margin-bottom: 8.7px;
}
.custom-select:hover {
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.custom-select__list {
display: block;
border-radius: 5px;
background-color: #fff;
padding: 5px 0;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
position: absolute;
z-index: 999;
left: 0;
top: calc(100% + 12px);
opacity: 0;
pointer-events: none;
transform: translateY(10px);
transition-property: transform, opacity;
transition-timing-function: ease-out;
transition-duration: 0.3s;
box-sizing: border-box;
}
.custom-select--drop .custom-select__list {
transform: translateY(0);
opacity: 1;
pointer-events: all;
}
.custom-select--drop .custom-select__placeholder::after {
transform: translateY(-80%) rotateX(360deg);
}
.custom-select__option {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5em 1.5em;
box-sizing: border-box;
cursor: pointer;
z-index: 0;
}
.custom-select__option-icon {
display: block;
flex-shrink: 0;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
}
.custom-select__option-icon img {
display: block;
width: 18px;
height: 15px;
max-height: 100%;
-o-object-fit: cover;
object-fit: cover;
margin: 0;
}
.custom-select__option-name {
display: block;
width: 100%;
text-transform: uppercase;
margin-right: 10px;
}
.custom-select__option-symbol {
display: block;
font-weight: bold;
}
.custom-select__option--select .custom-select__option-name {
color: #8dc641;
}
.custom-select__placeholder {
display: block;
width: 100%;
}
.custom-select__placeholder::after {
content: '';
display: block;
width: 0;
height: 0;
border: 6px solid transparent;
border-top-width: 6px;
border-bottom: 6px solid #616161;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-30%) rotateX(180deg);
transition-property: transform;
transition-timing-function: ease-out;
transition-duration: 0.3s;
}
.custom-select__option {
padding-right: calc(1.5em + 10px);
position: relative;
}
.custom-select {
display:inline-block;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
}
.custom-select:after {
display:block;
content: '';
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: relative;
bottom: -2px;
}
.custom-select:hover:after {
transform: scaleX(1);
}
.custom-select__placeholder .custom-select__option--select .custom-select__option-name:focus {
border-bottom: 2px solid #8dc641;
}
/* .custom-select__placeholder .custom-select__option::before,
.custom-select__placeholder .custom-select__option::after{
content: '';
position: absolute; bottom: -2px;
width: 0;
height: 2px;
background-color: #8dc641;
transition: width .3s ease;
}
.custom-select__placeholder .custom-select__option::before {
left: 50%;
}
.custom-select__placeholder .custom-select__option::after {
right: 50%;
}
.custom-select--drop .custom-select__placeholder .custom-select__option::before,
.custom-select--drop .custom-select__placeholder .custom-select__option::after {
width: 50%;
}
.custom-select__option:hover {
background-color: transparent;
} */
/* .container {
border: solid 2px #212121;
border-radius: 10px;
background-color: white;
box-sizing: border-box;
-webkit-box-sizing: border-box;
} */
.header {
display: flex;
align-items: center;
}
.indent-right {
display: flex;
width: 24px;
height: 24px;
background-image: url("https://cdn.privat24.ua/icons/file/ServiceCurrency.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
margin-right: 10px !important;
}
.btn {
display: inline-flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
position: relative;
width: 57px;
height: 44px;
font-size: 16px;
line-height: 1.5;
font-family: 'Open Sans', sans-serif;
font-weight: 600;
padding: 8px 16px;
border-radius: 4px;
transition-duration: 450ms;
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
word-break: normal;
color: rgba(0, 0, 0, 0.54);
background: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 12%) 0px 2px 4px 0px, rgb(0 0 0 / 12%) 0px 0px 4px 0px;
white-space: nowrap;
border-style: none;
border-width: 0px;
border-color: rgb(255, 255, 255);
margin: 0px;
cursor: pointer;
}
.btn:hover {
background-color: #F5F5F5;
box-shadow: 1px 1px 3px 3px #E0E0E0;
}
.swap-rate-container .btn-arrows {
transform: rotate(90deg);
opacity: 0.54;
transition: opacity 450ms cubic-bezier(0.23, 1, 0.32, 1);
position: absolute;
z-index: 0;
font-family: 'Open Sans', sans-serif;
}
.currency {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
input::placeholder {
font-family: 'Open Sans', sans-serif;
font-size: 16px;
}
.currency input {
background: transparent;
font-size: 16px;
line-height: 1.5;
text-align: right;
font-weight: 400;
color: rgba(0, 0, 0, 0.87);
border-style: none;
border-width: 0px;
border-radius: 0px;
background: transparent;
box-shadow: none;
outline: none;
width: 65%;
font-family: 'Open Sans', sans-serif;
background: transparent;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
margin-left: 15px
}
.currency input:hover {
display: block;
line-height: 1.5;
font-family: "Open Sans", sans-serif;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.currency input:focus {
border-bottom: 2px solid #8dc641;
border-bottom-color: transparent;
}
.select-placeholder {
background: rgb(255, 255, 255);
color: rgba(0, 0, 0, 0.38);
}
.swap-rate-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.rate {
color: black;
font-size: 15px;
padding: 0 10px;
background: #E0E0E0;
line-height: var(--tl-small);
padding: 8px;
font-family: 'Open Sans', sans-serif;
border-radius: 2px;
}
input::-webkit-inner-spin-button {
display: none !important;
}
.input-container {
position: relative;
width: 65%;
margin-left: 15px;
bottom: -1px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-container input:focus {
border-bottom: 2px solid #8dc641;
}
.input-box:hover + .input-border {
transform: scaleX(1);
}
.input-border {
display: block;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: absolute; bottom: 0; left: 0;
width: 102%;
}
#media (maz-width: 600px) {
.currency input {
width: 200px;
}
}
.display-none {
display: none;
}
/* for dropdown css*/
/* for input border css */
/* .input-container {
position: relative;
width: 65%;
margin-left: 15px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-border {
position: absolute; bottom: 0; left: 0;
width: 100%;
height: 2px;
}
.input-border::before,
.input-border::after{
content: '';
position: absolute; top: 0;
width: 0;
height: 100%;
background-color: #8dc641;
transition: width .3s ease;
}
.input-border::before {
left: 50%;
}
.input-border::after {
right: 50%;
}
.input-container input:focus + .input-border::before,
.input-container input:focus + .input-border::after {
width: 50%;
} */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Currency Converter</title>
<link rel="shortcut icon" href="currencies-icon-10.jpg" type="image/x-icon">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<div class="indent-right"></div>
<b>Конвертор валют</b>
</div>
<div class="currency">
<div class="custom-select" id="curr-one">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option custom-select__option--select" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option display-none" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-one" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
<div class="swap-rate-container">
<button class="btn" id="swap">
<div class="btn-arrows">
<div style="display: flex;">
<svg
height="24px" width="24px" version="1.1"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
<path d="M0 0h24v24H0z"></path>
<path
d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"
fill="#000"
fill-rule="nonzero"></path>
</g>
</svg>
</div>
</div>
</button>
<div class="rate" id="rate"></div>
</div>
<div class="currency">
<div class="custom-select" id="curr-two">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option custom-select__option--select" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option display-none" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-two" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
This snippet replaces the code given in your comment with:
const ratio = (1 * rateOne.rate / rateTwo.rate).toFixed(4);
function symbol(str) {
switch (str) {
case 'EUR': return '€';
case 'USD': return '$';
case 'GBP': return '£';
case 'UAH': return '₴';
default: return '?';
}
}
rateLabel.innerText = symbol(`${currencyOne}`) + `1 = ` + symbol(`${currencyTwo}`) + `${ratio} `;
That is, instead of showing the string representing the currency, show its symbol before the amount.
/*******************************************************************************
* Initialize the amount for the first currency
*******************************************************************************/
function initializeAmount() {
document.getElementById('amount-one').addEventListener('input', refreshAmount);
}
/*******************************************************************************
* Initialize the Swap trigger already existing in DOM
*******************************************************************************/
function initializeSwap() {
swap.addEventListener('click', () => {
const [selectOne, selectTwo] = document.querySelectorAll('.custom-select');
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const [valueOne, valueTwo] = [selectOne, selectTwo].map(
select => select.querySelector('.custom-select__option--select').dataset.value
);
//--------------------------------------------------------------------------
// Dirty trick to avoid problems when swapping currencies on the 2 DDs
// by finding the currencies not chosen by the two dropdowns
// and first selecting a third currency on the first dropdown
// before doing the actual swap
//--------------------------------------------------------------------------
const availableCurrencies = [];
const chosenCurrencies = [valueOne, valueTwo];
selectOne.querySelectorAll('.custom-select__list .custom-select__option-name').forEach((option) => {
availableCurrencies.push(option.innerText);
});
const notChosenCurrencies = availableCurrencies.filter(chosen => !chosenCurrencies.includes(chosen));
amountOne.value = amountTwo.value
selectOne.querySelector(`[data-value="${notChosenCurrencies[0]}"]`).click();
selectTwo.querySelector(`[data-value="${valueOne}"]`).click();
selectOne.querySelector(`[data-value="${valueTwo}"]`).click();
refreshConversionRatesAndAmount();
});
}
/*******************************************************************************
* Initialize the Currency Dropdowns already defined in the DOM
*******************************************************************************/
function initializeCurrencyDropdowns() {
//given the array of all .custom-select
[...document.querySelectorAll(".custom-select")]
//map()
.map(select => {
//inits dropdown options
let selected = select.querySelector(".custom-select__option--select");
if (selected) {
select.dataset.value = selected.dataset.value;
const placeholder = select.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
}
//adds click event listener to the list of options
select.querySelector(".custom-select__list").addEventListener("click", e => {
//--------------------------------------------------------------------------
// Logic to hide from the other DD the selected currency in this DD
//--------------------------------------------------------------------------
//fetches information about the currently selected dropdown
const thisDD = e.target.closest('.custom-select');
const currencyCurrentlySelected = e.target.closest('.custom-select__option').dataset.value;
//fetches information about the other dropdown
const otherDD_id = ((thisDD.id == 'curr-one' ? 'curr-two' : 'curr-one'));
const otherDD = document.getElementById(otherDD_id);
//removes the displaynone class to all the options in the other dropdown
otherDD.querySelectorAll('.custom-select__option').forEach((option) => {
option.classList.remove('display-none');
});
//adds the class displaynone to the currently selected currency in the second dropdown
otherDD.querySelector(`.custom-select__option[data-value="${currencyCurrentlySelected}"]`)
.classList.add('display-none');
//--------------------------------------------------------------------------
let target = e.target.closest(".custom-select__option");
if (target) {
let parent = target.closest(".custom-select");
parent
.querySelector(".custom-select__option--select")
.classList.remove("custom-select__option--select");
target.classList.add("custom-select__option--select");
let selected = parent.querySelector(".custom-select__option--select");
parent.dataset.value = selected.dataset.value;
const placeholder = parent.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
target.closest(".custom-select").classList.remove("custom-select--drop");
}
//--------------------------------------------------------------------------
refreshConversionRatesAndAmount();
});
//adds click event listener to the placeholder
select.querySelector(".custom-select__placeholder").addEventListener("click", e => {
let target = e.target.closest(".custom-select__placeholder");
if (target) {
target.closest(".custom-select").classList.toggle("custom-select--drop");
}
});
});
}
/*******************************************************************************
* Refresh the conversion rates and converted amount (and metadata)
* displayed in the respective labels
*******************************************************************************/
async function refreshConversionRatesAndAmount() {
const rates = await fetchConversionRates();
const currencyOne = getSelectedCurrencyOne();
const currencyTwo = getSelectedCurrencyTwo();
const rateOne = rates[currencyOne];
const rateTwo = rates[currencyTwo];
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const rateLabel = document.getElementById('rate');
const ratio = (1 * rateOne.rate / rateTwo.rate).toFixed(4);
function symbol(str) {
switch (str) {
case 'EUR':
return '€';
case 'USD':
return '$';
case 'GBP':
return '£';
case 'UAH':
return '₴';
default:
return '?';
}
}
rateLabel.innerText = symbol(`${currencyOne}`) + `1 = ` + symbol(`${currencyTwo}`) + `${ratio} `;
amountTwo.ratio = ratio;
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Refresh the amount only
*******************************************************************************/
function refreshAmount() {
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Fetch and return the conversion rates from a static url
*******************************************************************************/
async function fetchConversionRates() {
const url = 'https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json';
const response = await fetch(url);
const data = await response.json();
data.unshift({
"txt": "Українська гривня",
"rate": 1,
"cc": "UAH"
});
const ratesMapped = Object.assign({}, ...data.map((rate) => ({
[rate.cc]: rate
})));
return ratesMapped;
}
/*******************************************************************************
* Returns the Currency code selected on the first currency dropdown
*******************************************************************************/
function getSelectedCurrencyOne() {
const curr_oneDD = document.querySelector('#curr-one.custom-select');
return curr_oneDD.textContent.trim().slice(0, 3);
}
/*******************************************************************************
* Returns the Currency code selected on the second currency dropdown
*******************************************************************************/
function getSelectedCurrencyTwo() {
const curr_twoDD = document.querySelector('#curr-two.custom-select');
return curr_twoDD.textContent.trim().slice(0, 3);
}
initializeAmount();
initializeSwap();
initializeCurrencyDropdowns();
refreshConversionRatesAndAmount();
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 100vh;
margin: 0;
}
.custom-select {
display: block;
width: 150px;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 1;
margin-bottom: 8.7px;
}
.custom-select:hover {
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.custom-select__list {
display: block;
border-radius: 5px;
background-color: #fff;
padding: 5px 0;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
position: absolute;
z-index: 999;
left: 0;
top: calc(100% + 12px);
opacity: 0;
pointer-events: none;
transform: translateY(10px);
transition-property: transform, opacity;
transition-timing-function: ease-out;
transition-duration: 0.3s;
box-sizing: border-box;
}
.custom-select--drop .custom-select__list {
transform: translateY(0);
opacity: 1;
pointer-events: all;
}
.custom-select--drop .custom-select__placeholder::after {
transform: translateY(-80%) rotateX(360deg);
}
.custom-select__option {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5em 1.5em;
box-sizing: border-box;
cursor: pointer;
z-index: 0;
}
.custom-select__option-icon {
display: block;
flex-shrink: 0;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
}
.custom-select__option-icon img {
display: block;
width: 18px;
height: 15px;
max-height: 100%;
-o-object-fit: cover;
object-fit: cover;
margin: 0;
}
.custom-select__option-name {
display: block;
width: 100%;
text-transform: uppercase;
margin-right: 10px;
}
.custom-select__option-symbol {
display: block;
font-weight: bold;
}
.custom-select__option--select .custom-select__option-name {
color: #8dc641;
}
.custom-select__placeholder {
display: block;
width: 100%;
}
.custom-select__placeholder::after {
content: '';
display: block;
width: 0;
height: 0;
border: 6px solid transparent;
border-top-width: 6px;
border-bottom: 6px solid #616161;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-30%) rotateX(180deg);
transition-property: transform;
transition-timing-function: ease-out;
transition-duration: 0.3s;
}
.custom-select__option {
padding-right: calc(1.5em + 10px);
position: relative;
}
.custom-select {
display: inline-block;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
}
.custom-select:after {
display: block;
content: '';
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: relative;
bottom: -2px;
}
.custom-select:hover:after {
transform: scaleX(1);
}
.custom-select__placeholder .custom-select__option--select .custom-select__option-name:focus {
border-bottom: 2px solid #8dc641;
}
/* .custom-select__placeholder .custom-select__option::before,
.custom-select__placeholder .custom-select__option::after{
content: '';
position: absolute; bottom: -2px;
width: 0;
height: 2px;
background-color: #8dc641;
transition: width .3s ease;
}
.custom-select__placeholder .custom-select__option::before {
left: 50%;
}
.custom-select__placeholder .custom-select__option::after {
right: 50%;
}
.custom-select--drop .custom-select__placeholder .custom-select__option::before,
.custom-select--drop .custom-select__placeholder .custom-select__option::after {
width: 50%;
}
.custom-select__option:hover {
background-color: transparent;
} */
/* .container {
border: solid 2px #212121;
border-radius: 10px;
background-color: white;
box-sizing: border-box;
-webkit-box-sizing: border-box;
} */
.header {
display: flex;
align-items: center;
}
.indent-right {
display: flex;
width: 24px;
height: 24px;
background-image: url("https://cdn.privat24.ua/icons/file/ServiceCurrency.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
margin-right: 10px !important;
}
.btn {
display: inline-flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
position: relative;
width: 57px;
height: 44px;
font-size: 16px;
line-height: 1.5;
font-family: 'Open Sans', sans-serif;
font-weight: 600;
padding: 8px 16px;
border-radius: 4px;
transition-duration: 450ms;
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
word-break: normal;
color: rgba(0, 0, 0, 0.54);
background: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 12%) 0px 2px 4px 0px, rgb(0 0 0 / 12%) 0px 0px 4px 0px;
white-space: nowrap;
border-style: none;
border-width: 0px;
border-color: rgb(255, 255, 255);
margin: 0px;
cursor: pointer;
}
.btn:hover {
background-color: #F5F5F5;
box-shadow: 1px 1px 3px 3px #E0E0E0;
}
.swap-rate-container .btn-arrows {
transform: rotate(90deg);
opacity: 0.54;
transition: opacity 450ms cubic-bezier(0.23, 1, 0.32, 1);
position: absolute;
z-index: 0;
font-family: 'Open Sans', sans-serif;
}
.currency {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
input::placeholder {
font-family: 'Open Sans', sans-serif;
font-size: 16px;
}
.currency input {
background: transparent;
font-size: 16px;
line-height: 1.5;
text-align: right;
font-weight: 400;
color: rgba(0, 0, 0, 0.87);
border-style: none;
border-width: 0px;
border-radius: 0px;
background: transparent;
box-shadow: none;
outline: none;
width: 65%;
font-family: 'Open Sans', sans-serif;
background: transparent;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
margin-left: 15px
}
.currency input:hover {
display: block;
line-height: 1.5;
font-family: "Open Sans", sans-serif;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.currency input:focus {
border-bottom: 2px solid #8dc641;
border-bottom-color: transparent;
}
.select-placeholder {
background: rgb(255, 255, 255);
color: rgba(0, 0, 0, 0.38);
}
.swap-rate-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.rate {
color: black;
font-size: 15px;
padding: 0 10px;
background: #E0E0E0;
line-height: var(--tl-small);
padding: 8px;
font-family: 'Open Sans', sans-serif;
border-radius: 2px;
}
input::-webkit-inner-spin-button {
display: none !important;
}
.input-container {
position: relative;
width: 65%;
margin-left: 15px;
bottom: -1px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-container input:focus {
border-bottom: 2px solid #8dc641;
}
.input-box:hover+.input-border {
transform: scaleX(1);
}
.input-border {
display: block;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: absolute;
bottom: 0;
left: 0;
width: 102%;
}
#media (maz-width: 600px) {
.currency input {
width: 200px;
}
}
.display-none {
display: none;
}
/* for dropdown css*/
/* for input border css */
/* .input-container {
position: relative;
width: 65%;
margin-left: 15px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-border {
position: absolute; bottom: 0; left: 0;
width: 100%;
height: 2px;
}
.input-border::before,
.input-border::after{
content: '';
position: absolute; top: 0;
width: 0;
height: 100%;
background-color: #8dc641;
transition: width .3s ease;
}
.input-border::before {
left: 50%;
}
.input-border::after {
right: 50%;
}
.input-container input:focus + .input-border::before,
.input-container input:focus + .input-border::after {
width: 50%;
} */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Currency Converter</title>
<link rel="shortcut icon" href="currencies-icon-10.jpg" type="image/x-icon">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<div class="indent-right"></div>
<b>Конвертор валют</b>
</div>
<div class="currency">
<div class="custom-select" id="curr-one">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option custom-select__option--select" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option display-none" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-one" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
<div class="swap-rate-container">
<button class="btn" id="swap">
<div class="btn-arrows">
<div style="display: flex;">
<svg
height="24px" width="24px" version="1.1"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
<path d="M0 0h24v24H0z"></path>
<path
d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"
fill="#000"
fill-rule="nonzero"></path>
</g>
</svg>
</div>
</div>
</button>
<div class="rate" id="rate"></div>
</div>
<div class="currency">
<div class="custom-select" id="curr-two">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option custom-select__option--select" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option display-none" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-two" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Related
What's going on and what should be going on
I built a 3 d carousel popup. There are 3 slides; each slide must show a paragraph if it's "selected".
The z-index for the "selected" one always equals 1, the one on the right equals 0 and the one on the left equals -1.
I tried to add and remove visibility from the paragraphs if the z-index for the slide = 1. But unfortunately,your text it only works when I open the page because that's when the z-index is being checked I guess.
I would like to fade in the paragraphing that belongs to the slide every time it's "selected".
(I know my code for this might be 100% wrong.)
What I think should work...
I think I might need some sort of a swipe event listener but I'm not sure and I don't know how to do one of those.
HTML
`
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://kit.fontawesome.com/661fc68da9.js" crossorigin="anonymous"></script>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
<!-- Link Swiper's CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css" />
<script src="https://kit.fontawesome.com/661fc68da9.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script>
</head>
<body>
<button onclick="Size()"></button>
<div class="sizeGuidance">
<form data-multi-step2>
<div class="whatGuideD" data-step2>
<br>
<h1>The Size Guide</h1>
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div id="sw1" class="swiper-slide">
<span style="--i:1;"><button type="button" class="pickGuideD" ><i class="fa-solid fa-ruler fa-3x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px; " ></i>Quick Guide</button></span>
</div>
<div id="sw2" class="swiper-slide">
<span style="--i:2;"><button type="button" class="pickGuideD" ><i class="fa-solid fa-bullseye fa-2x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px" ></i>Super Guide</button></span>
</div>
<div id="sw3" class="swiper-slide">
<span style="--i:3;"><button type="button" class="pickGuideD" ><i class="fa-solid fa-square-poll-horizontal fa-2x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px" ></i>Size Chart</button></span>
</div>
</div>
<div class="swiper-pagination"></div>
<p id="d1" class="d1">Get to know your size in less than 1 minute. <br> - no measuring bands required.</p>
<p id="d2" class="d1">Get a more accurate size recommendation. <br> - no measuring bands required.</p>
<p id="d3" class="d1">You already know your measurments? <br> here is the size guide.</p>
</div>
</div>
</form>
<form data-multi-step2M>
<div class="whatGuideM" data-step2M>
<br>
<h1>The Size Guide</h1>
<br>
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<span style="--i:1;"><button type="button" class="pickGuideM" ><i class="fa-solid fa-ruler fa-3x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px; " ></i>Quick Guide</button></span>
</div>
<div class="swiper-slide">
<span style="--i:2;"><button type="button" class="pickGuideM" ><i class="fa-solid fa-bullseye fa-3x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px" ></i>Super Guide</button></span>
</div>
<div class="swiper-slide">
<span style="--i:3;"><button type="button" class="pickGuideM" ><i class="fa-solid fa-square-poll-horizontal fa-3x" style=" display: flex; flex-wrap: wrap;justify-content: center; margin-bottom: 20px; margin-top: 15px" ></i>Size Chart</button></span>
</div>
</div>
<div class="swiper-pagination"></div>
<p id="d1" ></p>
</div>
</div>
</form>
</div>
</body>
</html>
`
CSS
`
<style>
.d1 {
visibility: hidden;
opacity: 0;
transition: 0.5s ease-in-out;
position: absolute;
}
.d1.showDisc1{
visibility: visible;
opacity: 1;
transition: 0.5s ease-in-out;
}
.d2 {
visibility: hidden;
opacity: 0;
transition: 0.5s ease-in-out;
position: absolute;
}
.d2.showDisc2{
visibility: visible;
opacity: 1;
transition: 0.5s ease-in-out;
}
.d3 {
visibility: hidden;
opacity: 0;
transition: 0.5s ease-in-out;
position: absolute;
}
.d3.showDisc3{
visibility: visible;
opacity: 1;
transition: 0.5s ease-in-out;
}
</style>
<style>
#import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');
</style>
<style>
/*only desktop*/
.whatGuideD {
display: none;
}
#media only screen and (min-width: 900px) {
.whatGuideD {display: block;
}
.whatGuideM {display: none;
}
}
</style>
<!-- Demo styles -->
<style>
html {
height: -webkit-fill-available;
}
body {
position: relative;
height: 100%;
}
body {
background: #eee;
font-size: 14px;
color: #000;
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
height: -webkit-fill-available;
}
.swiper {
width: 100%;
padding-top: 0;
padding-bottom: 50px;
padding-left: 0;
padding-right: 0;
}
.swiper-slide {
background-position: center;
background-size: cover;
width: 60%;
max-width: 500px;
height: 75vh;
max-height: 500px;
border-radius: 15px;
background: rgb(238, 235, 241);
box-shadow: 10px 10px 10px -1px rgba(10, 99, 169, 0.16),
-10px -10px 10px -1px rgba(255, 255, 255, 0.70);
-webkit-box-reflect: below 1px linear-gradient(transparent, transparent, #fff6)
}
.swiper-slide button {
display: block;
width: 100%;
max-width: 500px;
}
h1 {
text-align: center;
Font-family: 'Bebas Neue', cursive;
font-size: 5vw;
margin: 0;
}
.pickGuideD {
Font-family: 'Bebas Neue', cursive;
text-transform: uppercase;
font-size: 48px;
font-weight: 500;
height: 100%;
background: rgb(238, 235, 241);
cursor: pointer;
border-radius: 10px;
color: rgb(0, 0, 0);
border: none;
text-align: center;
}
.pickGuideD:hover {
box-shadow: inset 10px 10px 10px -1px rgba(10, 99, 169, 0.16),
inset -10px -10px 10px -1px rgba(255, 255, 255, 0.70);
}
</style>
<style>
.pickGuideM {
Font-family: 'Bebas Neue', cursive;
text-transform: uppercase;
font-size: 24px;
font-weight: 500;
height: 100%;
background: rgb(238, 235, 241);
cursor: pointer;
border-radius: 10px;
color: rgb(0, 0, 0);
border: none;
text-align: center;
}
.pickGuideM:hover {
box-shadow: inset 10px 10px 10px -1px rgba(10, 99, 169, 0.16),
inset -10px -10px 10px -1px rgba(255, 255, 255, 0.70);
}
.close-button1D {
background-color: rgb(238, 235, 241);
color: rgb(0, 0, 0);
cursor: pointer;
font-size: 30px;
float: right;
margin-right: 40px;
border: 0;
}
::-webkit-scrollbar {
display: none;
}
</style>
<style>
.whatGuideD {
width: 100%;
height:100vh;
background: rgb(238, 235, 241);
text-align: center;
color: rgb(15, 15, 15);
visibility: hidden;
opacity: 0;
transition: 0.5s ease-in-out;
z-index: 3;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
}
.whatGuideD.active2{
visibility: visible;
opacity: 1;
position: fixed;
z-index: 4;
overflow-y: scroll;
transform: translate(-50%, -50%) scale(1);
}
.whatGuideM {
width: 100%;
height:100vh;
background: rgb(238, 235, 241);
text-align: center;
color: rgb(15, 15, 15);
visibility: hidden;
opacity: 0;
transition: 0.5s ease-in-out;
z-index: 3;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
}
.whatGuideM.active2M{
visibility: visible;
opacity: 1;
position: fixed;
z-index: 4;
overflow-y: hidden;
transform: translate(-50%, -50%) scale(1);
}
</style>
`
JS
`
<script>
var disc1 = document.querySelector("[showdiscrip1]")
function showdisc1() {
disc1.classList.add("disc");
}
function removedisc1() {
disc1.classList.remove("disc")
}
var disc2 = document.querySelector("[showdiscrip2]")
function showdisc2() {
disc2.classList.add("disc");
}
function removedisc2() {
disc2.classList.remove("disc")
}
var disc3 = document.querySelector("[showdiscrip3]")
function showdisc3() {
disc3.classList.add("disc");
}
function removedisc3() {
disc3.classList.remove("disc")
}
const mulitStepForm2 = document.querySelector("[data-multi-step2]")
const formSteps2 = [...mulitStepForm2.querySelectorAll("[data-step2]")]
let currentStep2 = formSteps2.findIndex(step2 => {
return step2.classList.contains("active2")
})
if (currentStep2 < 0) {
function SizeD() {
currentStep2 = 0
formSteps2[currentStep2].classList.add("active2")
showCurrentStep2();
window.scrollTo(0, 20);
}
}
mulitStepForm2.addEventListener("click", j => {
if (j.target.matches("[data-next]")) {
currentStep2++
} else if (j.target.matches("[data-closeguide]")) {
currentStep2 = -1
}
showCurrentStep2()
})
function showCurrentStep2() {
formSteps2.forEach((step2, index) => {
step2.classList.toggle("active2", index ===
currentStep2)
})
}
const mulitStepForm2M = document.querySelector("[data-multi-step2M]")
const formSteps2M = [...mulitStepForm2M.querySelectorAll("[data-step2M]")]
let currentStep2M = formSteps2M.findIndex(step2M => {
return step2M.classList.contains("active2M")
})
if (currentStep2M < 0) {
function SizeM() {
currentStep2M = 0
formSteps2M[currentStep2M].classList.add("active2M")
showCurrentStep2M();
window.scrollTo(0, 0);
}
}
mulitStepForm2M.addEventListener("click", j => {
if (j.target.matches("[data-nextM]")) {
currentStep2M++
} else if (j.target.matches("[data-closeguideM]")) {
currentStep2M = -1
}
showCurrentStep2M()
})
function showCurrentStep2M() {
formSteps2M.forEach((step2M, index) => {
step2M.classList.toggle("active2M", index ===
currentStep2M)
})
}
function Size() {
SizeD();
SizeM();
}
var swiper = new Swiper(".mySwiper", {
effect: "coverflow",
grabCursor: true,
centeredSlides: true,
slidesPerView: "auto",
coverflowEffect: {
rotate: 50,
stretch: 0,
depth: 500,
modifier: 1,
slideShadows: true,
},
pagination: {
el: ".swiper-pagination",
},
});
</script>
<script>
const sw1 = document.getElementById("sw1");
const sw2 = document.getElementById("sw2");
const sw3 = document.getElementById("sw3");
const sw1CS = window.getComputedStyle(sw1);
const sw2CS = window.getComputedStyle(sw2);
const sw3CS = window.getComputedStyle(sw3);
console.log(sw1CS.zIndex)
console.log(sw2CS.zIndex)
console.log(sw3CS.zIndex)
if (sw1CS.zIndex == 1) {
document.getElementById("d1").classList.add("showDisc1")
document.getElementById("d2").classList.remove("showDisc2")
}
if (sw2CS.zIndex == 1) {
document.getElementById("d2").classList.add("showDisc2")
document.getElementById("d1").classList.remove("showDisc1")
document.getElementById("d3").classList.remove("showDisc3")
}
if (sw3CS.zIndex == 1) {
document.getElementById("d3").classList.add("showDisc3")
document.getElementById("d2").classList.remove("showDisc2")
}
</script>
`
I want to style the bottom line in the dropdown so that when I clicked it was the same color as the input, i.e. to focus on that color, but I read that focus doesn't work with a div, there were other options, but they don't work for me, also I want my dropdowns and inputs to have this animation in the bottom line on hover: https://jsfiddle.net/andrewphoenix228/v1spzha5/3/
/*******************************************************************************
* Initialize the amount for the first currency
*******************************************************************************/
function initializeAmount() {
document.getElementById('amount-one').addEventListener('input', refreshAmount);
}
/*******************************************************************************
* Initialize the Swap trigger already existing in DOM
*******************************************************************************/
function initializeSwap() {
swap.addEventListener('click', () => {
const [selectOne, selectTwo] = document.querySelectorAll('.custom-select');
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const [valueOne, valueTwo] = [selectOne, selectTwo].map(
select => select.querySelector('.custom-select__option--select').dataset.value
);
//--------------------------------------------------------------------------
// Dirty trick to avoid problems when swapping currencies on the 2 DDs
// by finding the currencies not chosen by the two dropdowns
// and first selecting a third currency on the first dropdown
// before doing the actual swap
//--------------------------------------------------------------------------
const availableCurrencies = [];
const chosenCurrencies = [valueOne, valueTwo];
selectOne.querySelectorAll('.custom-select__list .custom-select__option-name').forEach((option)=>{
availableCurrencies.push( option.innerText );
});
const notChosenCurrencies = availableCurrencies.filter(chosen => !chosenCurrencies.includes(chosen));
amountOne.value = amountTwo.value
selectOne.querySelector(`[data-value="${notChosenCurrencies[0]}"]`).click();
selectTwo.querySelector(`[data-value="${valueOne}"]`).click();
selectOne.querySelector(`[data-value="${valueTwo}"]`).click();
refreshConversionRatesAndAmount();
});
}
/*******************************************************************************
* Initialize the Currency Dropdowns already defined in the DOM
*******************************************************************************/
function initializeCurrencyDropdowns() {
//given the array of all .custom-select
[...document.querySelectorAll(".custom-select")]
//map()
.map(select => {
//inits dropdown options
let selected = select.querySelector(".custom-select__option--select");
if (selected) {
select.dataset.value = selected.dataset.value;
const placeholder = select.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
}
//adds click event listener to the list of options
select.querySelector(".custom-select__list").addEventListener("click", e => {
//--------------------------------------------------------------------------
// Logic to hide from the other DD the selected currency in this DD
//--------------------------------------------------------------------------
//fetches information about the currently selected dropdown
const thisDD = e.target.closest('.custom-select');
const currencyCurrentlySelected = e.target.closest('.custom-select__option').dataset.value;
//fetches information about the other dropdown
const otherDD_id = ((thisDD.id == 'curr-one' ? 'curr-two' : 'curr-one'));
const otherDD = document.getElementById(otherDD_id);
//removes the displaynone class to all the options in the other dropdown
otherDD.querySelectorAll('.custom-select__option').forEach((option)=>{
option.classList.remove('display-none');
});
//adds the class displaynone to the currently selected currency in the second dropdown
otherDD.querySelector(`.custom-select__option[data-value="${currencyCurrentlySelected}"]`)
.classList.add('display-none');
//--------------------------------------------------------------------------
let target = e.target.closest(".custom-select__option");
if (target) {
let parent = target.closest(".custom-select");
parent
.querySelector(".custom-select__option--select")
.classList.remove("custom-select__option--select");
target.classList.add("custom-select__option--select");
let selected = parent.querySelector(".custom-select__option--select");
parent.dataset.value = selected.dataset.value;
const placeholder = parent.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
target.closest(".custom-select").classList.remove("custom-select--drop");
}
//--------------------------------------------------------------------------
refreshConversionRatesAndAmount();
});
//adds click event listener to the placeholder
select.querySelector(".custom-select__placeholder").addEventListener("click", e => {
let target = e.target.closest(".custom-select__placeholder");
if (target) {
target.closest(".custom-select").classList.toggle("custom-select--drop");
}
});
});
}
/*******************************************************************************
* Refresh the conversion rates and converted amount (and metadata)
* displayed in the respective labels
*******************************************************************************/
async function refreshConversionRatesAndAmount() {
const rates = await fetchConversionRates();
const currencyOne = getSelectedCurrencyOne();
const currencyTwo = getSelectedCurrencyTwo();
const rateOne = rates[currencyOne];
const rateTwo = rates[currencyTwo];
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const rateLabel = document.getElementById('rate');
const ratio = (1 * rateOne.rate / rateTwo.rate).toFixed(4);
rateLabel.innerText = `1 ${currencyOne} = ${ratio} ${currencyTwo}`;
amountTwo.ratio = ratio;
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Refresh the amount only
*******************************************************************************/
function refreshAmount() {
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Fetch and return the conversion rates from a static url
*******************************************************************************/
async function fetchConversionRates() {
const url = 'https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json';
const response = await fetch(url);
const data = await response.json();
data.unshift({
"txt": "Українська гривня",
"rate": 1,
"cc": "UAH"
});
const ratesMapped = Object.assign({}, ...data.map((rate) => ({[rate.cc]: rate})));
return ratesMapped;
}
/*******************************************************************************
* Returns the Currency code selected on the first currency dropdown
*******************************************************************************/
function getSelectedCurrencyOne() {
const curr_oneDD = document.querySelector('#curr-one.custom-select');
return curr_oneDD.textContent.trim().slice(0, 3);
}
/*******************************************************************************
* Returns the Currency code selected on the second currency dropdown
*******************************************************************************/
function getSelectedCurrencyTwo() {
const curr_twoDD = document.querySelector('#curr-two.custom-select');
return curr_twoDD.textContent.trim().slice(0, 3);
}
initializeAmount();
initializeSwap();
initializeCurrencyDropdowns();
refreshConversionRatesAndAmount();
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 100vh;
margin: 0;
}
.custom-select {
display: block;
width: 150px;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 1;
margin-bottom: 8.7px;
}
.custom-select:hover {
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.custom-select__list {
display: block;
border-radius: 5px;
background-color: #fff;
padding: 5px 0;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
position: absolute;
z-index: 999;
left: 0;
top: calc(100% + 12px);
opacity: 0;
pointer-events: none;
transform: translateY(10px);
transition-property: transform, opacity;
transition-timing-function: ease-out;
transition-duration: 0.3s;
box-sizing: border-box;
}
.custom-select--drop .custom-select__list {
transform: translateY(0);
opacity: 1;
pointer-events: all;
}
.custom-select--drop .custom-select__placeholder::after {
transform: translateY(-80%) rotateX(360deg);
}
.custom-select__option {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5em 1.5em;
box-sizing: border-box;
cursor: pointer;
z-index: 0;
}
.custom-select__option-icon {
display: block;
flex-shrink: 0;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
}
.custom-select__option-icon img {
display: block;
width: 18px;
height: 15px;
max-height: 100%;
-o-object-fit: cover;
object-fit: cover;
margin: 0;
}
.custom-select__option-name {
display: block;
width: 100%;
text-transform: uppercase;
margin-right: 10px;
}
.custom-select__option-symbol {
display: block;
font-weight: bold;
}
.custom-select__option--select .custom-select__option-name {
color: #8dc641;
}
.custom-select__placeholder {
display: block;
width: 100%;
}
.custom-select__placeholder::after {
content: '';
display: block;
width: 0;
height: 0;
border: 6px solid transparent;
border-top-width: 6px;
border-bottom: 6px solid #616161;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-30%) rotateX(180deg);
transition-property: transform;
transition-timing-function: ease-out;
transition-duration: 0.3s;
}
.custom-select__option {
padding-right: calc(1.5em + 10px);
position: relative;
}
.custom-select {
display:inline-block;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
}
.custom-select:after {
display:block;
content: '';
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: relative;
bottom: -2px;
}
.custom-select:hover:after { transform: scaleX(1);
}
.custom-select:focus {
border-bottom: 2px solid #8dc641;
}
/* .custom-select__placeholder .custom-select__option::before,
.custom-select__placeholder .custom-select__option::after{
content: '';
position: absolute; bottom: -2px;
width: 0;
height: 2px;
background-color: #8dc641;
transition: width .3s ease;
}
.custom-select__placeholder .custom-select__option::before {
left: 50%;
}
.custom-select__placeholder .custom-select__option::after {
right: 50%;
}
.custom-select--drop .custom-select__placeholder .custom-select__option::before,
.custom-select--drop .custom-select__placeholder .custom-select__option::after {
width: 50%;
}
.custom-select__option:hover {
background-color: transparent;
} */
/* .container {
border: solid 2px #212121;
border-radius: 10px;
background-color: white;
box-sizing: border-box;
-webkit-box-sizing: border-box;
} */
.header {
display: flex;
align-items: center;
}
.indent-right {
display: flex;
width: 24px;
height: 24px;
background-image: url("https://cdn.privat24.ua/icons/file/ServiceCurrency.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
margin-right: 10px !important;
}
.btn {
display: inline-flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
position: relative;
width: 57px;
height: 44px;
font-size: 16px;
line-height: 1.5;
font-family: 'Open Sans', sans-serif;
font-weight: 600;
padding: 8px 16px;
border-radius: 4px;
transition-duration: 450ms;
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
word-break: normal;
color: rgba(0, 0, 0, 0.54);
background: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 12%) 0px 2px 4px 0px, rgb(0 0 0 / 12%) 0px 0px 4px 0px;
white-space: nowrap;
border-style: none;
border-width: 0px;
border-color: rgb(255, 255, 255);
margin: 0px;
cursor: pointer;
}
.btn:hover {
background-color: #F5F5F5;
box-shadow: 1px 1px 3px 3px #E0E0E0;
}
.swap-rate-container .btn-arrows {
transform: rotate(90deg);
opacity: 0.54;
transition: opacity 450ms cubic-bezier(0.23, 1, 0.32, 1);
position: absolute;
z-index: 0;
font-family: 'Open Sans', sans-serif;
}
.currency {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
input::placeholder {
font-family: 'Open Sans', sans-serif;
font-size: 16px;
}
.currency input {
background: transparent;
font-size: 16px;
line-height: 1.5;
text-align: right;
font-weight: 400;
color: rgba(0, 0, 0, 0.87);
border-style: none;
border-width: 0px;
border-radius: 0px;
background: transparent;
box-shadow: none;
outline: none;
width: 65%;
font-family: 'Open Sans', sans-serif;
background: transparent;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
margin-left: 15px
}
.currency input:hover {
display: block;
line-height: 1.5;
font-family: "Open Sans", sans-serif;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
}
.currency input:focus {
border-bottom: 2px solid #8dc641;
border-bottom-color: transparent;
}
.select-placeholder {
background: rgb(255, 255, 255);
color: rgba(0, 0, 0, 0.38);
}
.swap-rate-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.rate {
color: black;
font-size: 15px;
padding: 0 10px;
background: #E0E0E0;
line-height: var(--tl-small);
padding: 8px;
font-family: 'Open Sans', sans-serif;
border-radius: 2px;
}
input::-webkit-inner-spin-button {
display: none !important;
}
.input-container {
position: relative;
width: 65%;
margin-left: 15px;
bottom: -1px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-container input:focus {
border-bottom: 2px solid #8dc641;
}
.input-box:hover + .input-border {
transform: scaleX(1);
}
.input-border {
display: block;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: absolute; bottom: 0; left: 0;
width: 102%;
}
#media (maz-width: 600px) {
.currency input {
width: 200px;
}
}
.display-none {
display: none;
}
/* for dropdown css*/
/* for input border css */
/* .input-container {
position: relative;
width: 65%;
margin-left: 15px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-border {
position: absolute; bottom: 0; left: 0;
width: 100%;
height: 2px;
}
.input-border::before,
.input-border::after{
content: '';
position: absolute; top: 0;
width: 0;
height: 100%;
background-color: #8dc641;
transition: width .3s ease;
}
.input-border::before {
left: 50%;
}
.input-border::after {
right: 50%;
}
.input-container input:focus + .input-border::before,
.input-container input:focus + .input-border::after {
width: 50%;
} */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Currency Converter</title>
<link rel="shortcut icon" href="currencies-icon-10.jpg" type="image/x-icon">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<div class="indent-right"></div>
<b>Конвертор валют</b>
</div>
<div class="currency">
<div class="custom-select" id="curr-one">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option custom-select__option--select" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option display-none" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-one" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
<div class="swap-rate-container">
<button class="btn" id="swap">
<div class="btn-arrows">
<div style="display: flex;">
<svg
height="24px" width="24px" version="1.1"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
<path d="M0 0h24v24H0z"></path>
<path
d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"
fill="#000"
fill-rule="nonzero"></path>
</g>
</svg>
</div>
</div>
</button>
<div class="rate" id="rate"></div>
</div>
<div class="currency">
<div class="custom-select" id="curr-two">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option custom-select__option--select" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option display-none" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-two" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
i have shared code hover effect on Input & dropdown. please check
/*******************************************************************************
* Initialize the amount for the first currency
*******************************************************************************/
function initializeAmount() {
document.getElementById('amount-one').addEventListener('input', refreshAmount);
}
/*******************************************************************************
* Initialize the Swap trigger already existing in DOM
*******************************************************************************/
function initializeSwap() {
swap.addEventListener('click', () => {
const [selectOne, selectTwo] = document.querySelectorAll('.custom-select');
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const [valueOne, valueTwo] = [selectOne, selectTwo].map(
select => select.querySelector('.custom-select__option--select').dataset.value
);
//--------------------------------------------------------------------------
// Dirty trick to avoid problems when swapping currencies on the 2 DDs
// by finding the currencies not chosen by the two dropdowns
// and first selecting a third currency on the first dropdown
// before doing the actual swap
//--------------------------------------------------------------------------
const availableCurrencies = [];
const chosenCurrencies = [valueOne, valueTwo];
selectOne.querySelectorAll('.custom-select__list .custom-select__option-name').forEach((option)=>{
availableCurrencies.push( option.innerText );
});
const notChosenCurrencies = availableCurrencies.filter(chosen => !chosenCurrencies.includes(chosen));
amountOne.value = amountTwo.value
selectOne.querySelector(`[data-value="${notChosenCurrencies[0]}"]`).click();
selectTwo.querySelector(`[data-value="${valueOne}"]`).click();
selectOne.querySelector(`[data-value="${valueTwo}"]`).click();
refreshConversionRatesAndAmount();
});
}
/*******************************************************************************
* Initialize the Currency Dropdowns already defined in the DOM
*******************************************************************************/
function initializeCurrencyDropdowns() {
//given the array of all .custom-select
[...document.querySelectorAll(".custom-select")]
//map()
.map(select => {
//inits dropdown options
let selected = select.querySelector(".custom-select__option--select");
if (selected) {
select.dataset.value = selected.dataset.value;
const placeholder = select.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
}
//adds click event listener to the list of options
select.querySelector(".custom-select__list").addEventListener("click", e => {
//--------------------------------------------------------------------------
// Logic to hide from the other DD the selected currency in this DD
//--------------------------------------------------------------------------
//fetches information about the currently selected dropdown
const thisDD = e.target.closest('.custom-select');
const currencyCurrentlySelected = e.target.closest('.custom-select__option').dataset.value;
//fetches information about the other dropdown
const otherDD_id = ((thisDD.id == 'curr-one' ? 'curr-two' : 'curr-one'));
const otherDD = document.getElementById(otherDD_id);
//removes the displaynone class to all the options in the other dropdown
otherDD.querySelectorAll('.custom-select__option').forEach((option)=>{
option.classList.remove('display-none');
});
//adds the class displaynone to the currently selected currency in the second dropdown
otherDD.querySelector(`.custom-select__option[data-value="${currencyCurrentlySelected}"]`)
.classList.add('display-none');
//--------------------------------------------------------------------------
let target = e.target.closest(".custom-select__option");
if (target) {
let parent = target.closest(".custom-select");
parent
.querySelector(".custom-select__option--select")
.classList.remove("custom-select__option--select");
target.classList.add("custom-select__option--select");
let selected = parent.querySelector(".custom-select__option--select");
parent.dataset.value = selected.dataset.value;
const placeholder = parent.querySelector(".custom-select__placeholder");
placeholder.innerHTML = "";
const pho = selected.cloneNode(true);
pho.classList.remove("custom-select__option--select");
placeholder.appendChild(pho);
target.closest(".custom-select").classList.remove("custom-select--drop");
}
//--------------------------------------------------------------------------
refreshConversionRatesAndAmount();
});
//adds click event listener to the placeholder
select.querySelector(".custom-select__placeholder").addEventListener("click", e => {
let target = e.target.closest(".custom-select__placeholder");
if (target) {
target.closest(".custom-select").classList.toggle("custom-select--drop");
}
});
});
}
/*******************************************************************************
* Refresh the conversion rates and converted amount (and metadata)
* displayed in the respective labels
*******************************************************************************/
async function refreshConversionRatesAndAmount() {
const rates = await fetchConversionRates();
const currencyOne = getSelectedCurrencyOne();
const currencyTwo = getSelectedCurrencyTwo();
const rateOne = rates[currencyOne];
const rateTwo = rates[currencyTwo];
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const rateLabel = document.getElementById('rate');
const ratio = (1 * rateOne.rate / rateTwo.rate).toFixed(4);
rateLabel.innerText = `1 ${currencyOne} = ${ratio} ${currencyTwo}`;
amountTwo.ratio = ratio;
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Refresh the amount only
*******************************************************************************/
function refreshAmount() {
const amountOne = document.getElementById('amount-one');
const amountTwo = document.getElementById('amount-two');
const newAmount = (amountOne.value * amountTwo.ratio).toFixed(2);
amountTwo.value = (amountOne.value !== '') ? newAmount : '';
}
/*******************************************************************************
* Fetch and return the conversion rates from a static url
*******************************************************************************/
async function fetchConversionRates() {
const url = 'https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json';
const response = await fetch(url);
const data = await response.json();
data.unshift({
"txt": "Українська гривня",
"rate": 1,
"cc": "UAH"
});
const ratesMapped = Object.assign({}, ...data.map((rate) => ({[rate.cc]: rate})));
return ratesMapped;
}
/*******************************************************************************
* Returns the Currency code selected on the first currency dropdown
*******************************************************************************/
function getSelectedCurrencyOne() {
const curr_oneDD = document.querySelector('#curr-one.custom-select');
return curr_oneDD.textContent.trim().slice(0, 3);
}
/*******************************************************************************
* Returns the Currency code selected on the second currency dropdown
*******************************************************************************/
function getSelectedCurrencyTwo() {
const curr_twoDD = document.querySelector('#curr-two.custom-select');
return curr_twoDD.textContent.trim().slice(0, 3);
}
initializeAmount();
initializeSwap();
initializeCurrencyDropdowns();
refreshConversionRatesAndAmount();
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 100vh;
margin: 0;
}
.custom-select {
display: block;
width: 150px;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 1;
margin-bottom: 8.7px;
}
/* .custom-select:hover {
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
} */
.custom-select__list {
display: block;
border-radius: 5px;
background-color: #fff;
padding: 5px 0;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
position: absolute;
z-index: 999;
left: 0;
top: calc(100% + 12px);
opacity: 0;
pointer-events: none;
transform: translateY(10px);
transition-property: transform, opacity;
transition-timing-function: ease-out;
transition-duration: 0.3s;
box-sizing: border-box;
}
.custom-select--drop .custom-select__list {
transform: translateY(0);
opacity: 1;
pointer-events: all;
}
.custom-select--drop .custom-select__placeholder::after {
transform: translateY(-80%) rotateX(360deg);
}
.custom-select__option {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5em 1.5em;
box-sizing: border-box;
cursor: pointer;
z-index: 0;
}
.custom-select__option-icon {
display: block;
flex-shrink: 0;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
}
.custom-select__option-icon img {
display: block;
width: 18px;
height: 15px;
max-height: 100%;
-o-object-fit: cover;
object-fit: cover;
margin: 0;
}
.custom-select__option-name {
display: block;
width: 100%;
text-transform: uppercase;
margin-right: 10px;
}
.custom-select__option-symbol {
display: block;
font-weight: bold;
}
.custom-select__option--select .custom-select__option-name {
color: #8dc641;
}
.custom-select__placeholder {
display: block;
width: 100%;
}
.custom-select__placeholder::after {
content: '';
display: block;
width: 0;
height: 0;
border: 6px solid transparent;
border-top-width: 6px;
border-bottom: 6px solid #616161;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-30%) rotateX(180deg);
transition-property: transform;
transition-timing-function: ease-out;
transition-duration: 0.3s;
}
.custom-select__option {
padding-right: calc(1.5em + 10px);
position: relative;
}
.custom-select {
display:inline-block;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
}
.custom-select:after {
display:block;
content: '';
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: relative;
bottom: -2px;
}
.custom-select:hover:after { transform: scaleX(1);
}
.custom-select:focus {
border-bottom: 2px solid #8dc641;
}
.header {
display: flex;
align-items: center;
}
.indent-right {
display: flex;
width: 24px;
height: 24px;
background-image: url("https://cdn.privat24.ua/icons/file/ServiceCurrency.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
margin-right: 10px !important;
}
.btn {
display: inline-flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
position: relative;
width: 57px;
height: 44px;
font-size: 16px;
line-height: 1.5;
font-family: 'Open Sans', sans-serif;
font-weight: 600;
padding: 8px 16px;
border-radius: 4px;
transition-duration: 450ms;
transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
word-break: normal;
color: rgba(0, 0, 0, 0.54);
background: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 12%) 0px 2px 4px 0px, rgb(0 0 0 / 12%) 0px 0px 4px 0px;
white-space: nowrap;
border-style: none;
border-width: 0px;
border-color: rgb(255, 255, 255);
margin: 0px;
cursor: pointer;
}
.btn:hover {
background-color: #F5F5F5;
box-shadow: 1px 1px 3px 3px #E0E0E0;
}
.swap-rate-container .btn-arrows {
transform: rotate(90deg);
opacity: 0.54;
transition: opacity 450ms cubic-bezier(0.23, 1, 0.32, 1);
position: absolute;
z-index: 0;
font-family: 'Open Sans', sans-serif;
}
.currency {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
input::placeholder {
font-family: 'Open Sans', sans-serif;
font-size: 16px;
}
.currency input {
background: transparent;
font-size: 16px;
line-height: 1.5;
text-align: right;
font-weight: 400;
color: rgba(0, 0, 0, 0.87);
border-style: none;
border-width: 0px;
border-radius: 0px;
background: transparent;
box-shadow: none;
outline: none;
width: 65%;
font-family: 'Open Sans', sans-serif;
background: transparent;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
margin-left: 15px
}
.currency input:hover {
display: block;
line-height: 1.5;
font-family: "Open Sans", sans-serif;
/* border-bottom: 2px solid rgba(0, 0, 0, 0.54); */
}
.currency input:focus {
border-bottom: 2px solid #8dc641;
border-bottom-color: transparent;
}
.select-placeholder {
background: rgb(255, 255, 255);
color: rgba(0, 0, 0, 0.38);
}
.swap-rate-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.rate {
color: black;
font-size: 15px;
padding: 0 10px;
background: #E0E0E0;
line-height: var(--tl-small);
padding: 8px;
font-family: 'Open Sans', sans-serif;
border-radius: 2px;
}
input::-webkit-inner-spin-button {
display: none !important;
}
.input-container {
position: relative;
width: 65%;
margin-left: 15px;
bottom: -1px;
}
.input-container input {
width: 100%;
margin-left: 0;
}
.input-box:hover + .input-border ,
.input-box:focus + .input-border ,
.input-box:active + .input-border {
transform: scaleX(1);
}
.input-border {
display: block;
border-bottom: 2px solid rgba(0, 0, 0, 0.54);
transform: scaleX(0);
transition: transform 250ms ease-in-out;
position: absolute; bottom: 0; left: 0;
width: 102%;
}
#media (maz-width: 600px) {
.currency input {
width: 200px;
}
}
.display-none {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Currency Converter</title>
<link rel="shortcut icon" href="currencies-icon-10.jpg" type="image/x-icon">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<div class="indent-right"></div>
<b>Конвертор валют</b>
</div>
<div class="currency">
<div class="custom-select" id="curr-one">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option custom-select__option--select" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option display-none" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-one" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
<div class="swap-rate-container">
<button class="btn" id="swap">
<div class="btn-arrows">
<div style="display: flex;">
<svg
height="24px" width="24px" version="1.1"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
<path d="M0 0h24v24H0z"></path>
<path
d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"
fill="#000"
fill-rule="nonzero"></path>
</g>
</svg>
</div>
</div>
</button>
<div class="rate" id="rate"></div>
</div>
<div class="currency">
<div class="custom-select" id="curr-two">
<div class="custom-select__placeholder"></div>
<div class="custom-select__list">
<div class="custom-select__option custom-select__option--select" data-value="UAH">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/UA.svg" />
</div>
<div class="custom-select__option-name">UAH</div>
<div class="custom-select__option-symbol">₴</div>
</div>
<div class="custom-select__option" data-value="GBP">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/GB.svg">
</div>
<div class="custom-select__option-name">GBP</div>
<div class="custom-select__option-symbol">£</div>
</div>
<div class="custom-select__option" data-value="EUR">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/EU.svg">
</div>
<div class="custom-select__option-name">EUR</div>
<div class="custom-select__option-symbol">€</div>
</div>
<div class="custom-select__option display-none" data-value="USD">
<div class="custom-select__option-icon">
<img src="https://cdn.privat24.ua/icons/file/US.svg">
</div>
<div class="custom-select__option-name">USD</div>
<div class="custom-select__option-symbol">$</div>
</div>
</div>
</div>
<div class="input-container">
<input type="number" id="amount-two" class="input-box" placeholder="200.00" />
<span class="input-border"></span>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
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
Been struggling hours now to find a solution for this.
I´m kinda new to JS so this is kinda tricky for me.
Was hoping someone here maybe had a bit of time to give me a solution.
Thanks.
If you click on the question mark (top right) it starts my animation to show the slider, and when you click the X it starts an animation to hide the slider.
I would like this to happen infinite. So when X has been clicked and the slider goes in, you can just click on the question mark and the slider pops up again, and so forth.
let press = document.getElementById("questionClick");
let show = document.getElementById("show");
let showOpt = document.getElementById("showSecond")
let hide = document.getElementById("exit");
let arrow = document.getElementById("nextArrow");
let info = document.getElementsByClassName("info");
show.classList.remove("info");
press.addEventListener("click", function () {
show.classList.add("info");
arrow.style.opacity = "0"
exit.style.opacity = "0"
setTimeout(function() {
exit.style.opacity = "100"
}, (400));
setTimeout(function() {
arrow.style.opacity = "100"
}, (1300));
});
hide.addEventListener("click", function () {
showOpt.style.width = "0em"
show.classList.add("infoExit");
hide.style.opacity = "40%"
setTimeout(function() {
arrow.style.opacity = "0"
}, (00));
setTimeout(function() {
exit.style.opacity = "0"
}, (800));
});
arrow.addEventListener("click", function() {
showOpt.style.width = "15em"
showOpt.style.height = "668px"
showOpt.style.padding = "1em"
});
const resultEl = document.getElementById('result');
const lengthEl = document.getElementById('length');
const uppercaseEl = document.getElementById('uppercase');
const lowercaseEl = document.getElementById('lowercase');
const numbersEl = document.getElementById('numbers');
const symbolsEl = document.getElementById('symbols');
const generateEl = document.getElementById('generate');
const clipboard = document.getElementById('clipboard');
const randomFunc = {
lower: getRandomLower,
upper: getRandomUpper,
number: getRandomNumber,
symbol: getRandomSymbol
}
clipboard.addEventListener('click', () => {
const textarea = document.createElement('textarea');
const password = resultEl.innerText;
if(!password) { return; }
textarea.value = password;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
alert('Password copied to clipboard');
});
generate.addEventListener('click', () => {
const length = +lengthEl.value;
const hasLower = lowercaseEl.checked;
const hasUpper = uppercaseEl.checked;
const hasNumber = numbersEl.checked;
const hasSymbol = symbolsEl.checked;
resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length);
});
function generatePassword(lower, upper, number, symbol, length) {
let generatedPassword = '';
const typesCount = lower + upper + number + symbol;
const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0]);
// Doesn't have a selected type
if(typesCount === 0) {
return '';
}
// create a loop
for(let i=0; i<length; i+=typesCount) {
typesArr.forEach(type => {
const funcName = Object.keys(type)[0];
generatedPassword += randomFunc[funcName]();
});
}
const finalPassword = generatedPassword.slice(0, length);
return finalPassword;
}
/* Generating random lower case characters */
function getRandomLower() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
/* Generating random upper case characters */
function getRandomUpper() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 65);
}
/* Generating random numbers */
function getRandomNumber() {
return +String.fromCharCode(Math.floor(Math.random() * 10) + 48);
}
/* Generating random symbols */
function getRandomSymbol() {
const symbols = '!##$%^&*(){}[]=<>/,.'
return symbols[Math.floor(Math.random() * symbols.length)];
}
.info {
animation: popup 1.6s;
animation-fill-mode:forwards;
}
#keyframes popup {
0% {
white-space: nowrap;
height: 4em;
width: 0em;
padding: 0.5em 1em 1em;
opacity: 0;
bottom: 13.9em; left: 9.7em;
color: rgba(0, 0, 0, 0);
}
40%, 50% {
width: 14em;
white-space: nowrap;
color: rgba(0, 0, 0, 0.555);
height: 4em;
padding: 0.5em 1em 1em;
opacity: 100;
bottom: 14em; left: 16.5em
}
60% {
white-space: normal;
}
90%, 100% {
height: 668px ;
width: 14em;
opacity: 100;
white-space: normal;
bottom: 0; left: 16.5em
}
}
.infoExit {
animation: popin 1.6s;
}
#exit {
padding: .3em .3em 0 0;
color: var(--clr-i-dim);
}
#exit:hover{
color: var(--clr-minibtn-inactive);
}
#keyframes popin {
0% {
height: 668px ;
width: 14em;
white-space: normal;
bottom: 0; left: 16.7em;
opacity: 100;
}
40%, 50% {
width: 14em;
white-space: nowrap;
height: 4em;
padding: 0.5em 1em 1em;
opacity: 100;
bottom: 14em; left: 16.5em;
}
50% {
white-space: nowrap;
color: rgba(0, 0, 0, 0.555);
}
80%, 100% {
white-space: nowrap;
height: 4em;
width: 0em;
padding: 0.5em 0em 1em;
opacity: 0;
bottom: 13.9em; left: 9.7em;
color: rgba(0, 0, 0, 0);
}
}
#infohead {
font-size: var(--fs-large);
font-weight: var(--fw-primary);
margin: 0.7em 0 0;
}
#show {
padding: 1em;
opacity: 0;
height: 668px ; width: 12em;
color: var(--txtclr-accent);
cursor: pointer;
font-size: var(--fs-info);
background: linear-gradient(45deg, #83b7da , #958bbb);
position: relative; left: 15.7em ; bottom: 0em; right: 0;
overflow: hidden;
border-radius: 0 .5em .5em 0;
}
#import url(https://fonts.googleapis.com/css?family=Montserrat);
#import url("https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700");
:root {
--ff-primary: 'Source Sans Pro', sans-serif;
--ff-accent: "Roboto", sans-serif;
--ff-option: "Open Sans", sans-serif;
--ff-number: 'Lato', sans-serif;
--fw-primary: 600;
--fw-accent: 400;
--fs-nomal: 1.2rem;
--fs-info: 1.3em;
--fs-large: 1.5rem;
--clr-primary: #50a3a2;
--clr-accent: #23235bdc;
--clr-white: rgba(255, 255, 255, 0.8);
--clr-btn: #530dc5;
--clr-btn-hover: #7031d4;
--clr-minibtn-hover: #4e694f;
--clr-minibtn-inactive: #943f3f;
--clr-shadow: 0px 5px 13px rgba(0, 0, 0, 0.993);
--clr-bg-primary: #4f65dd;
--clr-bg-accent: #aaa4a4 ;
--clr-i-dim: rgba(28, 28, 31, 0.637);
--txtclr-primary: rgba(255, 255, 255, 0.897);
--txtclr-accent: #212121 ;
}
* {
box-sizing: border-box;
}
html {
}
body {
background: var(--clr-primary);
color: var(--txtclr-primary);
font-family: var(--ff-primary);
display: flex; flex-direction: column;
align-items: center; justify-content: center;
min-height: 100vh;
background: -webkit-linear-gradient(top left, var(--clr-bg-primary) 0%, #ffffff 100%);
background: -moz-linear-gradient(top left, var(--clr-bg-primary) 0%, #ffffff 100%);
background: -o-linear-gradient(top left, var(--clr-bg-primary) 0%, #ffffff 100%);
background: linear-gradient(to bottom right, var(--clr-bg-primary) 0%, var(--clr-bg-accent) 100%);
}
h2 {
text-align: center;
margin: .2em 0 .8em;
}
h3 {
background: var(--clr-white);
color: var(--txtclr-accent);
font-family: var(--ff-option);
font-weight: var(--fw-accent);
line-height: 2rem;
}
label {
font-weight: var(--fw-primary);
font-family: var(--ff-option);
}
li {
margin: 1.8em 0;
list-style: none;
}
input {
cursor: pointer;
font-family: var(--ff-primary);
}
.container {
background: var(--clr-accent);
box-shadow: var(--clr-shadow);
position: absolute;
padding: 2em;
width:min(500px, 25em);
height: 668px;
}
.setting {
display: flex; justify-content: space-between; align-items: center;
}
.result-container {
background-color: rgba(168, 162, 162, 0.4);
display: flex; justify-content: flex-start; align-items: center;
position: relative;
font-size: var(--fs-nomal); letter-spacing: .14rem;
padding: 1em .6em; margin: 0 0 0.3em;
height: 2.6em;
}
.result-container #result {
word-wrap: break-word;
}
.result-container .btn {
font-size: 2rem;
position: absolute; top: 0.15em; right: 0.15em;
height: 1.3em; width: 1.3em;
}
.btn {
background: var(--clr-btn);
color: var(--txtclr-primary);
cursor: pointer;
border: none;
font-size: var(--fs-nomal);
padding: .6em;
}
.btn-large {
display: block;
width: 100%; height: 3.5em;
transition: .6s; overflow: hidden;
margin-top: 1.5em; border-radius: 4px;
transform: translateX(0%) translateY(0%);
}
#length {
height: 2.5em; width: 12em;
margin: 2em 0 1.7em; padding: 0 1em;
outline: 0;
color: var(--clr-bg-accent);
border: 0; border-radius: 5px;
outline: none;
cursor: pointer;
}
/* ICONS */
#questionClick, #exit, #exitOpt {
position: absolute; top: 0.3em; right: 0.3em;
}
#exit, #nextArrow {
transition: .2s; opacity: 0;
z-index: 999;
}
#nextArrow, #nextArrowOpt{
position: absolute; bottom: .4em; right: .4em;
}
#nextArrowOpt {
opacity: 100;
}
.far {
position: relative; bottom: 0.55em; right: 0.25em;
}
/* ICONS */
#keyframes jump {
0% {
top: 0.3em;
}
50% {
top: 0.32em;
}
100% {
top: 0.3em;
}
}
#showSecond {
position: absolute; left: 15.7em ; bottom: 0em; right: 0;
background: linear-gradient(45deg, #9fc4dd , #7d62dd);
opacity: 100;
white-space: normal;
height: 0px ; width: 0em;
cursor: pointer;
font-size: var(--fs-nomal); line-height: 1.5em;
position: relative; left: 19.2em ; bottom: 34.1em; right: 0;
overflow: hidden;
border-radius: 0 .5em .5em 0 ;
transition: 1s;
}
/* btn-large Effect */
button.btn-large:focus {
outline: 0;
}
button.btn-large:before {
content: '';
background: var(--clr-btn);
opacity: .5; filter: blur(30px);
transform: translateX(-100px) skewX(-15deg);
}
button.btn-large:after {
content: '';
display: block; position: absolute;
background: rgba(255, 255, 255, 0.2);
width: 30px; height: 100%;
left: 45px; top: 0;
opacity: 0; filter: blur(5px);
transform: translateX(-100px) skewX(-15deg);
}
button.btn-large:hover {
background: var(--clr-btn-hover);
}
button.btn-large:hover:before {
transform: translateX(300px) skewX(-15deg);
opacity: 0.6;
transition: .7s; }
button.btn-large:hover:after {
transform: translateX(300px) skewX(-15deg);
opacity: 1;
transition: .7s;
} /* btn-large Effect */
/* Mini button Effect */
.styled-checkbox {
position: absolute;
opacity: 100;
}
.styled-checkbox + label {
position: relative;
cursor: pointer;
padding: 0;
transition: 0.5s; }
.styled-checkbox + label:before {
content: '';
display: inline-block; vertical-align: text-top;
width: 20px; height: 20px;
background: var(--clr-minibtn-inactive); }
.styled-checkbox:hover + label:before {
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.342);
}
.styled-checkbox:focus + label:before {
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12); }
.styled-checkbox:checked + label:before {
background: var(--clr-minibtn-hover); }
.styled-checkbox:disabled + label {
color: #b8b8b8;
cursor: auto; }
.styled-checkbox:disabled + label:before {
box-shadow: none;
background: #ddd; }
.styled-checkbox:checked + label:after {
content: '';
position: absolute; left: 5px; top: 9px;
width: 2px; height: 2px;
background: white; box-shadow: 2px 0 0 white,
4px 0 0 white,
4px -2px 0 white,
4px -4px 0 white,
4px -6px 0 white,
4px -8px 0 white;
transform: rotate(45deg); }
/* Mini button Effect */
.range {
-webkit-appearance: none;
background: none;
}
.range::-webkit-slider-runnable-track {
background-color: #d7dbdd;
height: 6px;
border-radius: 3px;
border: 1px solid transparent;
}
.range::-ms-tooltip { display: none; /* display and visibility only */ }
.range::-webkit-slider-thumb {
-webkit-appearance: none;
border-radius: 100%;
background-color: #6574CF;
height: 18px;
width: 18px;
margin-top: -7px;
}
output {
min-width: 1em;
font-family: var(--ff-number);
font-size: 16px;
border-radius: 3px;
}
<!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="CS.css">
<script src="https://kit.fontawesome.com/79efab5353.js" crossorigin="anonymous"></script>
<script src="CS.js" defer></script>
<title>Document</title>
</head>
<body>
<div>
<h3 class="info" class="infoExit" id="show" class="show">
<span style = "">
<i id="exit" class="fas fa-times"></i>
</span>
<p id="infohead">Did you know?</p>
<br>
<br>
<b>6.850.000</b> passwords are getting hacked each day?
<br>
<br>
That is <b>158</b> each second!
<br>
<br>
Stop that from being you.
<br>
<br>
Let us help you make a strong password.
<span>
<i id="nextArrow" class="fas fa-chevron-circle-right"></i>
</span>
</h3>
</div>
<div class="container">
<h2>Password Generator</h2>
<div class="result-container">
<span id="result"></span>
<button class="btn" id="clipboard">
<section style = "font-size: 0.6em;">
<i class="far fa-clipboard"></i>
</section>
</button>
</div>
<span style = "font-size: 2em; color: rgb(209, 204, 214)">
<i id="questionClick" class="fas fa-question-circle"></i>
</span>
<div class="settings">
<div class="setting">
<label>Password length</label>
<input type="range" class="range" id="length" min='4' max='20' value='20' onmousemove="rangevalue1.value=value" />
<output id="rangevalue1"></output>
</div>
<div class="setting">
<label>Include uppercase letters</label>
<li>
<input class="styled-checkbox" id="uppercase" type="checkbox" value="value2" checked>
<label for="uppercase"></label>
</li>
</div>
<div class="setting">
<label>Include lowercase letters</label>
<li>
<input class="styled-checkbox" id="lowercase" type="checkbox" value="value2" checked>
<label for="lowercase"></label>
</li>
</div>
<div class="setting">
<label>Include numbers</label>
<li>
<input class="styled-checkbox" id="numbers" type="checkbox" value="value2" checked>
<label for="numbers"></label>
</li>
</div>
<div class="setting">
<label for="styled-checkbox-2">Include symbols</label>
<li>
<input class="styled-checkbox" id="symbols" type="checkbox" value="value2" checked>
<label for="symbols"></label>
</li>
</div>
</div>
<button class="btn btn-large" id="generate">
Generate password
</button>
<h3 id="showSecond">
<span style = "">
<i id="exitOpt" class="fas fa-times"></i>
</span>
<p id="infohead">What is a safe password?</p>
<br>
<br>
<b>7 characters</b> is normally the <b>minimum</b> length of a password with mixed symbols. <br><br>But it is highly recomended to use much more.
<br>
<br>
<b>The best possible password contains of 12 or more characters, mixed with symbols, numbers. lower & uppercase characters.</b>
<span>
<i id="nextArrowOpt" class="fas fa-chevron-circle-right"></i>
</span>
</h3>
</div>
</body>
</html>
Try using these function as below. Have updated the bare minimum.
press.addEventListener("click", function () {
show.classList.add("info");
show.classList.remove("infoExit");
arrow.style.opacity = "0"
exit.style.opacity = "0"
setTimeout(function() {
exit.style.opacity = "100"
}, (400));
setTimeout(function() {
arrow.style.opacity = "100"
}, (1300));
});
hide.addEventListener("click", function () {
setTimeout(function() {
show.classList.remove("info");
},1600);
showOpt.style.width = "0em"
hide.style.opacity = "40%"
show.classList.add("infoExit");
setTimeout(function() {
arrow.style.opacity = "0"
}, (00));
setTimeout(function() {
exit.style.opacity = "0"
}, (800));
});
I think your problem is your infoExit class that you don't remove after closing an idea would be to use maybe a toggle variable
//remove show.classList.remove("info");
let togglePress = false;
press.addEventListener("click", function () {
show.classList.remove("infoExit");
if (!togglePress) {
show.classList.add("info");
arrow.style.opacity = "0";
exit.style.opacity = "0";
setTimeout(function () {
exit.style.opacity = "100";
}, 400);
setTimeout(function () {
arrow.style.opacity = "100";
}, 1300);
togglePress = true;
}
})
hide.addEventListener("click", function () {
show.classList.remove("info");
if (togglePress) {
showOpt.style.width = "0em";
show.classList.add("infoExit");
hide.style.opacity = "40%";
setTimeout(function () {
arrow.style.opacity = "0";
}, 00);
setTimeout(function () {
exit.style.opacity = "0";
}, 800);
togglePress = false;
}
});
also you have several class attributes on your component which is not necessary
<h3 id="show">
<span id="exit">
<i class="fas fa-times"></i>
</span>
<p id="infohead">Did you know?</p>
<br />
<br />
<b>6.850.000</b> passwords are getting hacked each day?
<br />
<br />
That is <b>158</b> each second!
<br />
<br />
Stop that from being you.
<br />
<br />
Let us help you make a strong password.
<span>
<i id="nextArrow" class="fas fa-chevron-circle-right"></i>
</span>
</h3>
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.