I have these characteristics of these two images
#image1{
position:absolute;
left:29%;
top:40%;
background-image: url("../imgdrag/activity1.png");
width:63px;
height:38px;
}
#image2{
position:absolute;
left:29%;
top:40%;
background-image: url("../imgdrag/activity1red.png");
width:63px;
height:38px;
}
How can I replace the image1 with the image2 when I click on a button using a function
Example of switching state with jQuery
$('.replace').click(function(){
$('.image-holder').toggleClass('active');
})
#image1{
position:absolute;
left:29%;
top:40%;
background-image: url("../imgdrag/activity1.png");
width:63px;
height:38px;
z-index: 2;
background-color: blue;
}
#image2{
position:absolute;
left:29%;
top:40%;
background-image: url("../imgdrag/activity1red.png");
width:63px;
height:38px;
z-index: 1;
background-color: red;
}
.image-holder {
position: relative;
}
.image-holder.active #image2{
z-index: 3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="replace">Replace</button>
<div class="image-holder">
<div id="image1"></div>
<div id="image2"></div>
</div>
What I would recommend is to change your css to
#image1 {
position:absolute;
left:29%;
top:40%;
background-image: url("../imgdrag/activity1.png");
width:63px;
height:38px;
}
#image1.active {
background-image: url("../imgdrag/activity1red.png");
}
then if you are using jquery just add the new 'active' class, and remember to check first if it already has it.
$('button').on('click', function(e) {
var img = $('#image1');
if (!img.hasClass('active')) {
img.addClass('active');
}
});
// this with jQuery
$("#button").click(function() {
$('#image1').attr('id', '#image2');
});
or
function change(){
document.getElementById('#image1').setAttribute('id', '#image2');
}
You can use addEventListner Like the below code:
// Tempory you can use an hard coded to
const replaceImageSrc = "https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8aHVtYW58ZW58MHx8MHx8&w=1000&q=80"
// Replace Image
const image = document.getElementById('image');
// Replace button
const replaceBtn = document.getElementById('replace-img-btn');
const imagesReplace = (img) =>{
if(img != ""){
image.src=`${img}`
}else{
image.src=""
}
}
replaceBtn.addEventListener('click', ()=>{
imagesReplace(replaceImageSrc)
})
/* Fonts */
#import url("https://fonts.googleapis.com/css2?family=Nunito:wght#300&display=swap");
:root {
--primary-color: rgb(26, 26, 26);
--secondary-color: rgb(245, 245, 245);
--font-family: Nunito, sans-serif;
--box-shadow: rgb(0, 0, 0) 1px 1px 3px 0px inset, rgba(48, 48, 48, 0.5) -1px -1px 3px 1px inset;;
--all-transition: transform ease-in-out 0.3s 0s;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-family: var(--font-family);
}
.main-content{
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container{
width: 550px;
height: 250px;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
border-radius: 10px;
background-color: var(--primary-color);
}
.img-container{
width: 100%;
padding: 5px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
}
.img-container>img{
width: 100px;
border-radius: 10px;
}
.container>button{
width: 200px;
height: 35px;
border-radius: 5px;
border: none;
font-weight: bold;
margin-bottom: 15px;
box-shadow: var(--box-shadow);
background-color: var(--primary-color);
color: var(--secondary-color);
cursor: pointer;
transition: var(--all-transition);
}
/* Animation */
.container>button:hover{
transform: scale(1.08);
}
.container>button:active{
background-color: var(--secondary-color);
color: var(--primary-color);
box-shadow: none;
border: 1px solid var(--secondary-color);
}
<!doctype HTML>
<html>
<head>
<title>codedamn HTML Playground</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<div class="main-content">
<div class="container">
<div class="img-container">
<img src="https://images.unsplash.com/photo-1541963463532-d68292c34b19?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8Mnx8fGVufDB8fHx8&w=1000&q=80" id="image" alt="">
</div>
<button type="button" name="replace-img-btn" id="replace-img-btn">Replace Image</button>
</div>
</div>
<script src="/script.js"></script>
</body>
</html>
Related
So I am learning web dev, and I am a beginner. I have learned a tiny bit about DOM manipulation and I am facing a small issue with a click event.
The HTML CSS and JS code in codepen
Please click on the pizza image. When you click on it, the box shadow should remain even after you do not hover over the pizza and the gray link bar bellow is now yellow even when you don't hover over it. Click back on it and it returns to normal, neat!
Please now click on the pavlova (the sweet pinkish dessert). It doesn't work even though it shares the exact same css classes and everything when it comes to style.
I hope I have described my problem properly. If anything is not clear I will explain more. I have been on this for a while and I really don't know how to fix it. I will include the code here as well but everything is on code pen above, whichever is preferred.
const theFoodImg = document.querySelector('.food-img');
const recipeLink = document.querySelector('.recipe-link');
const linkIcon = document.querySelector('.fa-link');
const pinTopBar = document.querySelector('.fa-thumbtack');
const topBar = document.querySelector('#top-bar');
const pinColor = document.querySelector('.fa-thumbtack');
theFoodImg.addEventListener('click', function() {
if (theFoodImg.classList.contains('active')) {
theFoodImg.classList.remove('active');
theFoodImg.classList.remove('food-hover');
theFoodImg.classList.add('food-img');
recipeLink.classList.add('recipe-link');
recipeLink.classList.remove('click');
linkIcon.classList.add('white-link')
linkIcon.classList.remove('blue-link')
} else {
theFoodImg.classList.remove('food-img');
theFoodImg.classList.add('active');
recipeLink.classList.remove('recipe-link');
recipeLink.classList.add('click');
linkIcon.classList.remove('white-link')
linkIcon.classList.add('blue-link')
}
})
theFoodImg.addEventListener('mouseenter', function() {
if (theFoodImg.classList.contains('active') !== true) {
theFoodImg.classList.add('food-hover');
}
})
if (topBar.classList.contains('fix')) {
pinColor.style.color = 'goldenrod';
}
pinTopBar.addEventListener('click', function() {
if (topBar.classList.contains('fix') !== true) {
topBar.classList.add('fix');
pinColor.style.color = 'goldenrod';
} else {
topBar.classList.remove('fix');
pinColor.style.color = 'black';
}
})
/* css reset */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
text-decoration: none;
}
body {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
}
hr {
width: 80%;
margin: 0 auto;
background-color: black;
box-shadow: 0 0 15px gold;
}
/* banner and title styles */
div#banner {
background: url(https://i.ibb.co/MgBrNdY/background-img.jpg);
box-shadow: inset 0 0 0 9000em rgba(68, 68, 68, 0.5);
background-size: cover;
height: 50vh;
/* change later for media queries */
}
/* title style */
h1#large-screen-title {
color: goldenrod;
text-align: center;
padding: 0.5em;
font-size: 4em;
}
div#top-bar {
background-color: rgb(255, 250, 234);
height: min-content;
}
.fix {
position: fixed;
height: 15%;
right: 0;
left: 0;
top: 0;
box-shadow: 0 0 20px goldenrod;
}
img#odin-logo {
height: 5em;
}
i.fa-thumbtack {
float: right;
padding: 1em;
}
i.fa-thumbtack:hover {
cursor: pointer;
}
#media only screen and (min-width: 700px) {
div#banner {
height: 80vh;
}
h1#title-index {
height: 60vh;
color: transparent;
border: 0px solid white;
}
div#top-bar {
text-align: center;
}
}
/* recipe card styles */
div#recipe-card-container {
padding-top: 5em;
padding-left: 0.5em;
padding-right: 0.5em;
display: grid;
grid-template-columns: 1fr;
justify-content: center;
align-items: center;
gap: 2em;
}
/*each recipe card */
div#recipe-card-container>div.each-recipe {
display: grid;
gap: 2em;
margin-bottom: 5em;
justify-content: center;
}
div#recipe-card-container div.recipe-img {
/* background-color: red; */
width: 100%;
height: 50vh;
border-radius: 3px;
transition: 450ms;
}
/*recipe link within each card */
div.recipe-link {
background-color: lightgray;
text-align: center;
padding-top: 1em;
padding: 0.5em;
transition: 450ms;
border-radius: 0.3em;
}
div.recipe-link:hover {
background-color: #eece1a;
transition: 450ms;
}
/* when clicked add this style */
.click {
background-color: #eece1a;
text-align: center;
padding-top: 1em;
padding: 0.5em;
border-radius: 0.3em;
transition: 450ms;
width: 100%;
margin: 0 auto;
}
/**/
i.fa-link {
float: left;
}
div.recipe-link:hover>i.fa-link {
color: rgb(0, 0, 255, 0.5);
}
/*when clicked, target i.fa-link color */
.white-link {
color: white;
}
.blue-link {
color: rgb(0, 0, 255, 0.5);
}
/* food image style on card */
.food-img {
height: 100%;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
img.food-img {
width: 100%;
}
img.food-hover:hover,
.active {
box-shadow: 0 0 20px rgb(189, 80, 12);
height: 105%;
object-fit: cover;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
/*grey bar with copyright*/
div.copy {
background-color: rgba(0, 0, 0, 0.54);
margin-top: 2em;
padding: 2em;
color: white;
text-align: center;
}
#media only screen and (min-width: 1020px) {
div#recipe-card-container {
padding-left: 0;
padding-right: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
gap: 2em;
margin-top: 2em;
box-shadow: inset 0 500px rgb(85, 63, 63);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../style.css" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Odin Recipes</title>
</head>
<body>
<div id="banner">
<div id="top-bar" class="fix">
<img src="https://i.ibb.co/7nhgfNJ/odin-logo.png" alt="" id="odin-logo" />
<i class="fa-solid fa-thumbtack"></i>
</div>
</div>
<br />
<br />
<hr />
<h1 id="large-screen-title">Odin Recipes</h1>
<br /><br />
<hr />
<div id="recipe-card-container">
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/mDCCZTW/pizza.jpg" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/pizza.html">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pizza Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/5cQCFWP/pavlova.png" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/pavlova.html">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="/recipes/images/" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova Recipe
</div>
</a>
</div>
</div>
<div class="copy">Copyright © 2022</div>
<script src="https://kit.fontawesome.com/fb94170dc7.js" crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>
Check out the below snippet. i have updated theFoodImg variable to theFoodImgs and leveraged querySelectorAll to get a node list of all the .food-img class elements.
Then use a foreach loop on the nodelist to loop it and add your listeners.
You may want to update more of your variables from querySelector to querySelectorAll. I have done this one to get you headed down the correct path.
**Edit added a recipeLink class. cant key off of a class in the selector that is being added and removed. The snippet should be in full working order now.
const theFoodImgs = document.querySelectorAll('.food-img'),
pinTopBar = document.querySelector('.fa-thumbtack'),
topBar = document.querySelector('#top-bar'),
pinColor = document.querySelector('.fa-thumbtack');
let recipeLink, linkIcon;
theFoodImgs.forEach(function (el) {
el.addEventListener('click', function() {
recipeLink = this.parentNode.parentNode.querySelector('.recipeLink');
linkIcon = this.parentNode.parentNode.querySelector('.fa-link');
if(this.classList.contains('active')){
this.classList.remove('active');
this.classList.remove('food-hover');
this.classList.add('food-img');
recipeLink.classList.add('recipe-link');
recipeLink.classList.remove('click');
linkIcon.classList.add('white-link')
linkIcon.classList.remove('blue-link')
} else {
this.classList.remove('food-img');
this.classList.add('active');
recipeLink.classList.remove('recipe-link');
recipeLink.classList.add('click');
linkIcon.classList.remove('white-link')
linkIcon.classList.add('blue-link')
}
});
el.addEventListener('mouseenter', function(){
if (el.classList.contains('active') !== true) {
el.classList.add('food-hover');
}
})
});
if(topBar.classList.contains('fix')) {
pinColor.style.color = 'goldenrod';
}
pinTopBar.addEventListener('click', function() {
if(topBar.classList.contains('fix') !== true) {
topBar.classList.add('fix');
pinColor.style.color = 'goldenrod';
}
else {
topBar.classList.remove('fix');
pinColor.style.color = 'black';
}
})
/* css reset */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
text-decoration: none;
}
body {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
}
hr {
width: 80%;
margin: 0 auto;
background-color: black;
box-shadow: 0 0 15px gold;
}
/* banner and title styles */
div#banner {
background: url(https://i.ibb.co/MgBrNdY/background-img.jpg);
box-shadow: inset 0 0 0 9000em rgba(68, 68, 68, 0.5);
background-size: cover;
height: 50vh; /* change later for media queries */
}
/* title style */
h1#large-screen-title {
color: goldenrod;
text-align: center;
padding: 0.5em;
font-size: 4em;
}
div#top-bar {
background-color: rgb(255, 250, 234);
height: min-content;
}
.fix {
position: fixed;
height: 15%;
right: 0;
left: 0;
top: 0;
box-shadow: 0 0 20px goldenrod;
}
img#odin-logo {
height: 5em;
}
i.fa-thumbtack {
float: right;
padding: 1em;
}
i.fa-thumbtack:hover {
cursor: pointer;
}
#media only screen and (min-width: 700px) {
div#banner {
height: 80vh;
}
h1#title-index {
height: 60vh;
color: transparent;
border: 0px solid white;
}
div#top-bar {
text-align: center;
}
}
/* recipe card styles */
div#recipe-card-container {
padding-top: 5em;
padding-left: 0.5em;
padding-right: 0.5em;
display: grid;
grid-template-columns: 1fr;
justify-content: center;
align-items: center;
gap: 2em;
}
/*each recipe card */
div#recipe-card-container > div.each-recipe {
display: grid;
gap: 2em;
margin-bottom: 5em;
justify-content: center;
}
div#recipe-card-container div.recipe-img {
/* background-color: red; */
width: 100%;
height: 50vh;
border-radius: 3px;
transition: 450ms;
}
/*recipe link within each card */
div.recipe-link {
background-color: lightgray;
text-align: center;
padding-top: 1em;
padding: 0.5em;
transition: 450ms;
border-radius: 0.3em;
}
div.recipe-link:hover {
background-color: #eece1a;
transition: 450ms;
}
/* when clicked add this style */
.click {
background-color: #eece1a;
text-align: center;
padding-top: 1em;
padding: 0.5em;
border-radius: 0.3em;
transition: 450ms;
width: 100%;
margin: 0 auto;
}
/**/
i.fa-link {
float: left;
}
div.recipe-link:hover > i.fa-link {
color: rgb(0, 0, 255, 0.5);
}
/*when clicked, target i.fa-link color */
.white-link {
color: white;
}
.blue-link {
color: rgb(0, 0, 255, 0.5);
}
/* food image style on card */
.food-img {
height: 100%;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
img.food-img {
width: 100%;
}
img.food-hover:hover,
.active {
box-shadow: 0 0 20px rgb(189, 80, 12);
height: 105%;
object-fit: cover;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
/*grey bar with copyright*/
div.copy {
background-color: rgba(0, 0, 0, 0.54);
margin-top: 2em;
padding: 2em;
color: white;
text-align: center;
}
#media only screen and (min-width: 1020px) {
div#recipe-card-container {
padding-left: 0;
padding-right: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
gap: 2em;
margin-top: 2em;
box-shadow: inset 0 500px rgb(85, 63, 63);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../style.css" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Odin Recipes</title>
</head>
<body>
<div id="banner">
<div id="top-bar" class="fix">
<a href="https://www.theodinproject.com/"
><img src="https://i.ibb.co/7nhgfNJ/odin-logo.png" alt="" id="odin-logo"
/></a>
<i class="fa-solid fa-thumbtack"></i>
</div>
</div>
<br />
<br />
<hr />
<h1 id="large-screen-title">Odin Recipes</h1>
<br /><br />
<hr />
<div id="recipe-card-container">
<div class="each-recipe">
<div class="recipe-img">
<img
src="https://i.ibb.co/mDCCZTW/pizza.jpg"
alt=""
class="food-img food-hover"
/>
</div>
<a href="/recipes/pizza.html">
<div class="recipe-link recipeLink">
<i class="fa-solid fa-link white-link"></i>Click here for Pizza
Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/5cQCFWP/pavlova.png" alt="" class="food-img food-hover"/>
</div>
<a href="/recipes/pavlova.html">
<div class="recipe-link recipeLink">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img
src="/recipes/images/"
alt=""
class="food-img food-hover"
/>
</div>
<a href="/recipes/">
<div class="recipe-link recipeLink">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova
Recipe
</div>
</a>
</div>
</div>
<div class="copy">Copyright © 2022</div>
<script
src="https://kit.fontawesome.com/fb94170dc7.js"
crossorigin="anonymous"
></script>
<script src="app.js"></script>
</body>
</html>
I simplified the process to not query ANY loops. Instead I'm assigning the event handler to the parent of the recipes. Then I look for the active element and REMOVE the active class from the recipe itself. Instead of adding/removing classes from each element, I simply add an active class to the recipe parent and use CSS to modify the children of the active class.
const recipes = document.querySelector("#recipe-card-container")
recipes.addEventListener("click", function(el) {
let target = el.target;
if (target.className.indexOf("food-img") > -1) {
let active = document.querySelector(".each-recipe.active");
if (active) {
active.classList.remove("active");
}
target.parentNode.parentNode.classList.add("active");
}
});
/* css reset */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
text-decoration: none;
}
body {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
}
hr {
width: 80%;
margin: 0 auto;
background-color: black;
box-shadow: 0 0 15px gold;
}
/* banner and title styles */
div#banner {
background: url(https://i.ibb.co/MgBrNdY/background-img.jpg);
box-shadow: inset 0 0 0 9000em rgba(68, 68, 68, 0.5);
background-size: cover;
height: 50vh;
/* change later for media queries */
}
/* title style */
h1#large-screen-title {
color: goldenrod;
text-align: center;
padding: 0.5em;
font-size: 4em;
}
div#top-bar {
background-color: rgb(255, 250, 234);
height: min-content;
}
.fix {
position: fixed;
height: 15%;
right: 0;
left: 0;
top: 0;
box-shadow: 0 0 20px goldenrod;
}
img#odin-logo {
height: 5em;
}
i.fa-thumbtack {
float: right;
padding: 1em;
}
i.fa-thumbtack:hover {
cursor: pointer;
}
#media only screen and (min-width: 700px) {
div#banner {
height: 80vh;
}
h1#title-index {
height: 60vh;
color: transparent;
border: 0px solid white;
}
div#top-bar {
text-align: center;
}
}
/* recipe card styles */
div#recipe-card-container {
padding-top: 5em;
padding-left: 0.5em;
padding-right: 0.5em;
display: grid;
grid-template-columns: 1fr;
justify-content: center;
align-items: center;
gap: 2em;
}
/*each recipe card */
div#recipe-card-container>div.each-recipe {
display: grid;
gap: 2em;
margin-bottom: 5em;
justify-content: center;
}
div#recipe-card-container div.recipe-img {
/* background-color: red; */
width: 100%;
height: 50vh;
border-radius: 3px;
transition: 450ms;
}
/*recipe link within each card */
div.recipe-link {
background-color: lightgray;
text-align: center;
padding-top: 1em;
padding: 0.5em;
transition: 450ms;
border-radius: 0.3em;
}
div.recipe-link:hover {
background-color: #eece1a;
transition: 450ms;
}
/* when clicked add this style */
.active .recipe-link {
background-color: #eece1a;
text-align: center;
padding-top: 1em;
padding: 0.5em;
border-radius: 0.3em;
transition: 450ms;
width: 100%;
margin: 0 auto;
}
/**/
i.fa-link {
float: left;
}
div.recipe-link:hover>i.fa-link {
color: rgb(0, 0, 255, 0.5);
}
/*when clicked, target i.fa-link color */
.recipe-link i {
color: white;
}
.each-recipe.active i {
color: rgb(0, 0, 255, 0.5);
}
/* food image style on card */
.food-img {
height: 100%;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
img.food-img {
width: 100%;
}
img.food-hover:hover,
.each-recipe.active img {
box-shadow: 0 0 20px rgb(189, 80, 12);
height: 105%;
object-fit: cover;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
/*grey bar with copyright*/
div.copy {
background-color: rgba(0, 0, 0, 0.54);
margin-top: 2em;
padding: 2em;
color: white;
text-align: center;
}
#media only screen and (min-width: 1020px) {
div#recipe-card-container {
padding-left: 0;
padding-right: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
gap: 2em;
margin-top: 2em;
box-shadow: inset 0 500px rgb(85, 63, 63);
}
}
<div id="recipe-card-container">
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/mDCCZTW/pizza.jpg" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/pizza.html">
<div class="recipe-link">
<i class="fa-solid fa-link"></i>Click here for Pizza Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/5cQCFWP/pavlova.png" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/pavlova.html">
<div class="recipe-link">
<i class="fa-solid fa-link"></i>Click here for Pavlova Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="/recipes/images/" alt="" class="food-img food-hover" />
</div>
<a href="/recipes/">
<div class="recipe-link">
<i class="fa-solid fa-link"></i>Click here for Pavlova Recipe
</div>
</a>
</div>
</div>
<div class="copy">Copyright © 2022</div>
<script src="https://kit.fontawesome.com/fb94170dc7.js" crossorigin="anonymous"></script>
It finally worked!
// const theFoodImg = document.querySelector('.food-img');
// const recipeLink = document.querySelector('.recipe-link');
// const linkIcon = document.querySelector('.fa-link');
const pinTopBar = document.querySelector('.fa-thumbtack');
const topBar = document.querySelector('#top-bar');
const pinColor = document.querySelector('.fa-thumbtack');
// theFoodImg.addEventListener('click', function() {
// if(theFoodImg.classList.contains('active')){
// theFoodImg.classList.remove('active');
// theFoodImg.classList.remove('food-hover');
// theFoodImg.classList.add('food-img');
// recipeLink.classList.add('recipe-link');
// recipeLink.classList.remove('click');
// linkIcon.classList.add('white-link')
// linkIcon.classList.remove('blue-link')
// } else {
// theFoodImg.classList.remove('food-img');
// theFoodImg.classList.add('active');
// recipeLink.classList.remove('recipe-link');
// recipeLink.classList.add('click');
// linkIcon.classList.remove('white-link');
// linkIcon.classList.add('blue-link');
// }
// })
// theFoodImg.addEventListener('mouseenter', function(){
// if (theFoodImg.classList.contains('active') !== true) {
// theFoodImg.classList.add('food-hover');
// }
// })
if(topBar.classList.contains('fix')) {
pinColor.style.color = 'goldenrod';
}
pinTopBar.addEventListener('click', function() {
if(topBar.classList.contains('fix') !== true) {
topBar.classList.add('fix');
pinColor.style.color = 'goldenrod';
}
else {
topBar.classList.remove('fix');
pinColor.style.color = 'black';
}
})
const recipeContainer = document.querySelector('div#recipe-card-container');
const linkIcon = document.querySelectorAll('.fa-link');
recipeContainer.addEventListener('click',function(event){
if(event.target.classList.contains('food-img') || event.target.classList.contains('food-hover')){
if(event.target.classList.contains('active')==false) {
event.target.classList.remove('food-img');
event.target.classList.add('active');
const recipeImg = event.target.parentElement;
const aTag = recipeImg.nextElementSibling;
const recipeLink = aTag.firstElementChild;
const linkIcon = recipeLink.firstElementChild;
recipeLink.classList.remove('recipe-link');
recipeLink.classList.add('click');
linkIcon.classList.remove('white-link');
linkIcon.classList.add('blue-link');
if(!event.target.classList.contains('food-hover')){
event.target.classList.add('food-hover');
}
} else {
event.target.classList.remove('active');
event.target.classList.remove('food-hover');
event.target.classList.add('food-img');
const recipeImg = event.target.parentElement;
const aTag = recipeImg.nextElementSibling;
const recipeLink = aTag.firstElementChild;
const linkIcon = recipeLink.firstElementChild;
linkIcon.classList.add('white-link');
linkIcon.classList.remove('blue-link');
recipeLink.classList.add('recipe-link');
recipeLink.classList.remove('click');
}
}
})
/* css reset */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
text-decoration: none;
}
body {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
}
hr {
width: 80%;
margin: 0 auto;
background-color: black;
box-shadow: 0 0 15px gold;
}
/* banner and title styles */
div#banner {
background: url(https://i.ibb.co/MgBrNdY/background-img.jpg);
box-shadow: inset 0 0 0 9000em rgba(68, 68, 68, 0.5);
background-size: cover;
height: 50vh; /* change later for media queries */
}
/* title style */
h1#large-screen-title {
color: goldenrod;
text-align: center;
padding: 0.5em;
font-size: 4em;
}
div#top-bar {
background-color: rgb(255, 250, 234);
height: min-content;
}
.fix {
position: fixed;
height: 15%;
right: 0;
left: 0;
top: 0;
box-shadow: 0 0 20px goldenrod;
}
img#odin-logo {
height: 5em;
}
i.fa-thumbtack {
float: right;
padding: 1em;
}
i.fa-thumbtack:hover {
cursor: pointer;
}
#media only screen and (min-width: 700px) {
div#banner {
height: 80vh;
}
h1#title-index {
height: 60vh;
color: transparent;
border: 0px solid white;
}
div#top-bar {
text-align: center;
}
}
/* recipe card styles */
div#recipe-card-container {
padding-top: 5em;
padding-left: 0.5em;
padding-right: 0.5em;
display: grid;
grid-template-columns: 1fr;
justify-content: center;
align-items: center;
gap: 2em;
}
/*each recipe card */
div#recipe-card-container > div.each-recipe {
display: grid;
gap: 2em;
margin-bottom: 5em;
justify-content: center;
}
div#recipe-card-container div.recipe-img {
/* background-color: red; */
width: 100%;
height: 45vh;
border-radius: 3px;
transition: 450ms;
}
/*recipe link within each card */
div.recipe-link {
background-color: lightgray;
text-align: center;
padding-top: 1em;
padding: 0.5em;
transition: 450ms;
border-radius: 0.3em;
width: 100%;
margin: 0 auto;
}
div.recipe-link:hover {
background-color: #eece1a;
transition: 450ms;
}
/* when clicked add this style */
.click {
background-color: #eece1a;
text-align: center;
padding-top: 1em;
padding: 0.5em;
border-radius: 0.3em;
transition: 450ms;
width: 100%;
margin: 0 auto;
}
/**/
i.fa-link {
float: left;
}
div.recipe-link:hover > i.fa-link {
color: rgb(0, 0, 255, 0.5);
}
/*when clicked, target i.fa-link color */
.white-link {
color: white;
}
.blue-link {
color: rgb(0, 0, 255, 0.5);
}
/* food image style on card */
.food-img {
height: 100%;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
img.food-img {
width: 100%;
}
img.food-hover {
box-shadow: 0 0 20px #eee;
}
img.food-img:hover,
.active {
box-shadow: 0 0 20px rgb(189, 80, 12);
height: 105%;
object-fit: cover;
border-radius: 50%;
border: 4px solid rgba(189, 80, 12, 0.637);
transition: 450ms;
cursor: pointer;
}
/*grey bar with copyright*/
div.copy {
background-color: rgba(0, 0, 0, 0.54);
margin-top: 30vh;
padding: 2em;
color: white;
text-align: center;
}
#media only screen and (min-width: 1020px) {
div#recipe-card-container {
padding-left: 0;
padding-right: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
gap: 2em;
margin-top: 2em;
box-shadow: inset 0 700px rgb(85, 63, 63);
}
}
#media only screen and (max-width: 720px) {
div#recipe-card-container div.recipe-img {
width: 100%;
height: 30vh;
border-radius: 3px;
object-fit: cover;
}
.food-img {
height: 30vh;
border-radius: 20px;
border: 4px solid rgba(189, 80, 12, 0.637);
cursor: pointer;
object-fit: cover;
}
img.food-hover:hover,
.active {
box-shadow: 0 0 20px rgb(189, 80, 12);
height: 32vh;
object-fit: cover;
border-radius: 20px;
border: 4px solid rgba(189, 80, 12, 0.637);
cursor: pointer;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../style.css" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Odin Recipes</title>
</head>
<body>
<div id="banner">
<div id="top-bar" class="fix">
<a href="https://www.theodinproject.com/"
><img src="https://i.ibb.co/7nhgfNJ/odin-logo.png" alt="" id="odin-logo"
/></a>
<i class="fa-solid fa-thumbtack"></i>
</div>
</div>
<br />
<br />
<hr />
<h1 id="large-screen-title">Odin Recipes</h1>
<br /><br />
<hr />
<div id="recipe-card-container">
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/mDCCZTW/pizza.jpg" alt="" class="food-img" />
</div>
<a href="/recipes/pizza.html">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pizza
Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="https://i.ibb.co/5cQCFWP/pavlova.png" alt="" class="food-img" />
</div>
<a href="/recipes/pavlova.html">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova
Recipe
</div>
</a>
</div>
<div class="each-recipe">
<div class="recipe-img">
<img src="/recipes/images/" alt="" class="food-img" />
</div>
<a href="/recipes/">
<div class="recipe-link">
<i class="fa-solid fa-link white-link"></i>Click here for Pavlova
Recipe
</div>
</a>
</div>
</div>
<div class="copy">Copyright © 2022</div>
<script
src="https://kit.fontawesome.com/fb94170dc7.js"
crossorigin="anonymous"
></script>
<script src="app.js"></script>
</body>
</html>
I would like to show a content when a button is pressed and change colour of the active button. Currently I'm able to perform both the operation individually, but I don't get how to merge these functionalities.
To show the content, my script looks like :
function changedata(parameter){
if(parameter==0){
document.getElementById('myreport').style.display = 'none';
document.getElementById('mydata').style.display = 'block';
}
else{
document.getElementById('mydata').style.display = 'none';
document.getElementById('myreport').style.display = 'flex';
}
}
* {
margin: 0;
padding: 0;
}
#mydata{
display:none;
font-size: 25;
}
.chartCard {
width: 100vw;
height: calc(80vh - 100px);
background: rgb(133, 43, 43);
display: flex;
align-items: center;
justify-content: center;
}
.chartBox {
width: 650px;
padding: 30px;
border-radius: 20px;
margin: 1px 22px;
border: solid 3px rgba(255, 26, 104, 1);
background: white;
}
.button:hover{
background-color: #005201;
color: rgb(255, 253, 250);;
}
.button {
background-color: rgb(69, 9, 188);
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
margin: 2px 2px;
transition-duration: 0.4s;
cursor: pointer;
}
<button class="button" onclick="changedata(1)">Myreport</button>
<button class="button" onclick="changedata(0)">Mydata</button>
<div id="mydata">
<h1>This is my Data</h1>
</div>
<div class="chartCard" id="myreport">
<div class="chartBox">
<p>Ram</p>
</div>
<div class="chartBox">
<p>Shyam</p>
</div>
</div>
I want to highlight the active button so i added .highlight{background-color: green;} in css and a new script as :
var buttons = document.querySelectorAll("button");
for (button in buttons) {
buttons[button].onclick = function() {
console.log('test')
buttons.forEach(function(btn){
btn.classList.remove('highlight');
})
this.classList.add('highlight');
}
}
function changedata(parameter){
if(parameter==0){
document.getElementById('myreport').style.display = 'none';
document.getElementById('mydata').style.display = 'block';
}
else{
document.getElementById('mydata').style.display = 'none';
document.getElementById('myreport').style.display = 'flex';
}
}
var buttons = document.querySelectorAll("button");
for (button in buttons) {
buttons[button].onclick = function() {
console.log('test')
buttons.forEach(function(btn){
btn.classList.remove('highlight');
})
this.classList.add('highlight');
}
}
* {
margin: 0;
padding: 0;
}
#mydata{
display:none;
font-size: 25;
}
.chartCard {
width: 100vw;
height: calc(90vh - 100px);
background: rgb(133, 43, 43);
display: flex;
align-items: center;
justify-content: center;
}
.chartBox {
width: 650px;
padding: 30px;
border-radius: 20px;
margin: 1px 22px;
border: solid 3px rgba(255, 26, 104, 1);
background: white;
}
.button:hover{
background-color: #005201;
color: rgb(255, 253, 250);;
}
.button {
background-color: rgb(69, 9, 188);
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
margin: 2px 2px;
transition-duration: 0.4s;
cursor: pointer;
}
.highlight {
background-color: green;
}
<button class="button" onclick="changedata(1)">Myreport</button>
<button class="button" onclick="changedata(0)">Mydata</button>
<div id="mydata">
<h1>This is my Data</h1>
</div>
<div class="chartCard" id="myreport">
<div class="chartBox">
<p>Ram</p>
</div>
<div class="chartBox">
<p>Shyam</p>
</div>
</div>
How to achieve both the functionality together ? kindly looking for help.
You just need to remove the class in changedata() and add it to the clicked element.
document.querySelectorAll(".button").forEach((e) => {
e.classList.remove('highlight');
});
event.target.classList.add('highlight');
function changedata(parameter){
document.querySelectorAll(".button").forEach((e) => {
e.classList.remove('highlight');
});
event.target.classList.add('highlight');
if(parameter==0){
document.getElementById('myreport').style.display = 'none';
document.getElementById('mydata').style.display = 'block';
}
else{
document.getElementById('mydata').style.display = 'none';
document.getElementById('myreport').style.display = 'flex';
}
}
* {
margin: 0;
padding: 0;
}
#mydata{
display:none;
font-size: 25;
}
.chartCard {
width: 100vw;
height: calc(90vh - 100px);
background: rgb(133, 43, 43);
display: flex;
align-items: center;
justify-content: center;
}
.chartBox {
width: 650px;
padding: 50px;
border-radius: 20px;
margin: 1px 22px;
border: solid 3px rgba(255, 26, 104, 1);
background: white;
}
.button:hover{
background-color: #005201;
color: rgb(255, 253, 250);;
}
.button {
background-color: rgb(69, 9, 188);
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
margin: 2px 2px;
transition-duration: 0.4s;
cursor: pointer;
}
.highlight {
background-color: green;
}
<button class="button highlight" onclick="changedata(1)">Myreport</button>
<button class="button" onclick="changedata(0)">Mydata</button>
<div id="mydata">
<h1>This is my Data</h1>
</div>
<div class="chartCard" id="myreport">
<div class="chartBox">
<p>Ram</p>
</div>
<div class="chartBox">
<p>Shyam</p>
</div>
</div>
You are using .onclick on the buttons twice. By doing this the first function will be overwritten by second function. Solution to that is addEventListener() method. Which attaches an specific event handler to an element. You can also add more than one handler for an event if you use this method.
Keeping functions separate is considered as good practice in JS. In snippet below there is a function named setActiveClass(). There are two parameters first is element and second one is for element's classname. If you want to change the classname you just have to change the value of variable activeClassName rather changing it everywhere.
let myReportBtn = document.getElementById("reportBtn");
let myDataBtn = document.getElementById("dataBtn");
let buttons = document.querySelectorAll("button");
function changedata(bool) {
let myReport = document.getElementById('myreport');
let myData = document.getElementById('mydata');
const activeClassName = 'highlight';
if (!bool) {
myReport.style.display = 'none';
myData.style.display = 'block';
setActiveClass(myDataBtn, activeClassName);
} else {
myData.style.display = 'none';
myReport.style.display = 'flex';
setActiveClass(myReportBtn, activeClassName);
}
}
function setActiveClass(elem, classname){
buttons.forEach(function(btn) {
btn.classList.remove(`${classname}`);
});
elem.classList.add(`${classname}`);
}
myReportBtn.addEventListener("click", function(){
changedata(true);
});
myDataBtn.addEventListener("click", function(){
changedata(false);
});
* {
margin: 0;
padding: 0;
}
#mydata {
display: none;
font-size: 25;
}
.chartCard {
width: 100vw;
height: calc(50vh - 100px);
background: rgb(133, 43, 43);
display: flex;
align-items: center;
justify-content: center;
}
.chartBox {
width: 650px;
padding: 50px;
border-radius: 20px;
margin: 1px 22px;
border: solid 3px rgba(255, 26, 104, 1);
background: white;
}
.button:hover {
background-color: #005201;
color: rgb(255, 253, 250);
}
.button {
background-color: rgb(69, 9, 188);
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
margin: 2px 2px;
transition-duration: 0.4s;
cursor: pointer;
}
.highlight {
background-color: yellow;
}
<!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">
<title>Document</title>
</head>
<body>
<button class="button" id="reportBtn">Myreport</button>
<button class="button" id="dataBtn">Mydata</button>
<div id="mydata">
<h1>This is my Data</h1>
</div>
<div class="chartCard" id="myreport">
<div class="chartBox">
<p>Ram</p>
</div>
<div class="chartBox">
<p>Shyam</p>
</div>
</div>
</body>
</html>
I made a website in which content changes when the user clicks on a toggle switch, the price changes from monthly to annual, and vice versa when a user clicks on the toggle i.e. the h2 with the class monthly gets displayed when toggler is checked(true) and the h2 with class annual gets displayed when toggler is unchecked(false).
function refreshPage(){
window.location.reload();
}
const toggler = document.querySelector("#switch");
const annual = document.querySelectorAll(".annual");
const monthly = document.querySelectorAll(".monthly");
window.onload = function priceChange(){
if (toggler.checked === false) {
monthly.forEach(hideMonthly);
function hideMonthly(item) {
item.style.display = "none";
}
} else if (toggler.checked === true ) {
annual.forEach(hideAnnual);
function hideAnnual(item) {
item.style.display = "none";
}
}
}
:root {
--gradient: linear-gradient(to bottom right, hsl(236, 72%, 79%), hsl(237, 63%, 64%));
--gradient-900: hsl(237, 63%, 64%);
--neutral-grey-100: hsl(240, 78%, 98%);
--neutral-grey-300: hsl(234, 14%, 74%);
--neutral-grey-600: hsl(233, 13%, 49%);
--neutral-grey-900: hsl(232, 13%, 33%);
--neutral-100: #fff;
--neutral-900: #000;
}
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 15px;
font-family: 'Montserrat', sans-serif;
background: #F6F6FE url("../images/bg-top.svg") no-repeat;
background-position: top right -170px;
text-align: center;
}
.neutral-grey-100 {
color: var(--neutral-grey-100);
}
.neutral-grey-300 {
color: var(--neutral-grey-300);
}
.neutral-grey-600 {
color: var(--neutral-grey-600);
}
.neutral-grey-900 {
color: var(--neutral-grey-900);
}
h1 {
font-size: 2em;
margin-bottom: .8em;
}
h2 {
font-size: 3em;
margin: 1rem 0;
}
.container {
width: 85%;
margin: 0 auto;
}
.header {
padding: 2.4em;
}
.card {
display: flex;
flex-direction: column;
background-color: var(--neutral-100);
border-radius: .8em;
padding: 1em 2.6em;
margin-bottom: 2.5em;
box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
}
.card:nth-child(odd) {
background: var(--gradient);
color: var(--neutral-100);
}
.card > div:not(:last-child) {
border-bottom: 1px solid rgba(183, 184, 194, 0.45);
}
.card-inverse > div:not(:last-child) {
border-bottom: 1px solid rgba(255, 255, 255, 0.35);
}
section div {
padding: 1em 0;
}
.button {
text-transform: uppercase;
padding: 1em 2em;
margin: 2.6em 0 1.2em 0;
background: var(--gradient);
border: 1px solid var(--neutral-100);
border-radius: 6px;
text-decoration: none;
color: var(--neutral-100);
}
.button:hover, .button:focus {
background: var(--neutral-100);
border: 1px solid hsl(237, 63%, 24%);
color: var(--gradient-900);
outline: none;
}
.button-inverse {
background: var(--neutral-100);
text-decoration: none;
color: var(--gradient-900);
}
.button-inverse:hover, .button-inverse:focus {
background: hsl(237, 63%, 64%);
border: 1px solid var(--neutral-100);
color: var(--neutral-100);
outline: none;
}
.attribution {
font-size: 11px;
text-align: center;
margin-bottom: 1rem;
}
.attribution a {
color: hsl(228, 45%, 44%);
}
/*-------- TOGGLER --------*/
.toggle {
display: flex;
justify-content: center;
align-items: center;
}
input[type=checkbox]{
height: 0;
width: 0;
visibility: hidden;
}
label {
cursor: pointer;
text-indent: -9999px;
width: 65px;
height: 35px;
background: var(--gradient);
display: block;
border-radius: 100px;
position: relative;
margin: 1.4em;
}
label:after {
content: '';
position: absolute;
top: 4px;
left: 4px;
width: 27px;
height: 27px;
background: #fff;
border-radius: 110px;
-webkit-transition: all 350ms;
-moz-transition: all 350ms;
transition: all 350ms;
}
input:checked + label {
background: var(--gradient);
}
input + label:hover, input + label:focus-within {
background: hsl(236, 72%, 81%)
}
input:checked + label:after {
transform: translate3d(114%, 0, 0);
}
#media (min-width: 1440px) {
body {
font-size: 16px;
background-image: url("../images/bg-top.svg"), url("../images/bg-bottom.svg");
background-repeat: no-repeat, no-repeat;
background-position: 100% 0%, 0% 130%;
background-size: 24%, 24%;
}
.container {
display: grid;
grid-template-areas:
"header header header"
"basic professional master"
"attribution attribution attribution";
align-items: center;
width: 65%;
}
.header {
grid-area: header;
}
h2 {
font-size: 4em;
}
h3 {
font-size: 1.3033333333333335em;
}
.card-inverse {
padding: 3em 2em;
}
.card {
margin-bottom: 0;
}
#basic {
grid-area: basic;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
#professional {
grid-area: professional;
}
#master {
grid-area: master;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.attribution {
grid-area: attribution;
margin-top: 4em;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
<link rel="stylesheet" href="css/style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#700&display=swap" rel="stylesheet">
<script defer src="js/script.js"></script>
<title>Frontend Mentor | Pricing component with toggle</title>
</head>
<body>
<div class="container">
<section class="header">
<h1 class="neutral-grey-900">Our Pricing</h1>
<div class="toggle neutral-grey-300">
Annually
<input type="checkbox" id="switch" onClick="refreshPage()"/><label for="switch">Toggle</label>
<!-- <label class="switch"><input type="checkbox" name="toggler" id="toggler" onClick="refreshPage()"/> <figure></figure>
</label> -->
Monthly
</div>
</section>
<section class="card" id="basic">
<div>
<h3 class="neutral-grey-600">Basic</h3>
<h2 class="neutral-grey-900 monthly">$19.99</h2>
<h2 class="neutral-grey-900 annual">$199.99</h2>
</div>
<div class="neutral-grey-600">500 GB Storage</div>
<div class="neutral-grey-600">2 Users Allowed</div>
<div class="neutral-grey-600">Send up to 3 GB</div>
<a class="button button-main" href="">Learn More</a>
</section>
<section class="card card-inverse" id="professional">
<div>
<h3>Professional</h3>
<h2 class="monthly">$24.99</h2>
<h2 class="annual">$249.99</h2>
</div>
<div>1 TB Storage</div>
<div>5 Users Allowed</div>
<div>Send up to 10 GB</div>
<a class="button button-inverse" href="">Learn More</a>
</section>
<section class="card" id="master">
<div>
<h3 class="neutral-grey-600">Master</h3>
<h2 class="neutral-grey-900 monthly">$39.99</h2>
<h2 class="neutral-grey-900 annual">$399.99</h2>
</div>
<div class="neutral-grey-600">2 TB Storage</div>
<div class="neutral-grey-600">10 Users Allowed</div>
<div class="neutral-grey-600">Send up to 20 GB</div>
<a class="button button-main" href="">Learn More</a>
</section>
<div class="attribution">
Challenge by Frontend Mentor.
Coded by Sachin Jadhav.
</div>
</div>
</body>
</html>
The toggle is working in Firefox but not in Chrome, I am not able to figure out what's wrong with my javascript.
Your code is relying on Firefox remembering the state of the input and restoring it before the load handler fires on subsequent page loads. That's not something you can rely on cross-browser.
Instead, just handle the toggle without refreshing. And instead of manually looping the items, you can use a class on their container (or even body) to control them:
toggler.addEventListener("click", () => {
document.body.classList.toggle("show-monthly", toggler.checked);
});
(And removing refreshPage entirely.)
With this additional CSS:
body .monthly {
display: none;
}
body.show-monthly .monthly {
display: block;
}
body.show-monthly .annual {
display: none;
}
(Note that the second argument of classList.toggle doesn't work on obsolete browsers like IE, so you may need an if/else for those.)
const toggler = document.querySelector("#switch");
const annual = document.querySelectorAll(".annual");
const monthly = document.querySelectorAll(".monthly");
toggler.addEventListener("click", () => {
document.body.classList.toggle("show-monthly", toggler.checked);
});
body .monthly {
display: none;
}
body.show-monthly .monthly {
display: block;
}
body.show-monthly .annual {
display: none;
}
:root {
--gradient: linear-gradient(to bottom right, hsl(236, 72%, 79%), hsl(237, 63%, 64%));
--gradient-900: hsl(237, 63%, 64%);
--neutral-grey-100: hsl(240, 78%, 98%);
--neutral-grey-300: hsl(234, 14%, 74%);
--neutral-grey-600: hsl(233, 13%, 49%);
--neutral-grey-900: hsl(232, 13%, 33%);
--neutral-100: #fff;
--neutral-900: #000;
}
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 15px;
font-family: 'Montserrat', sans-serif;
background: #F6F6FE url("../images/bg-top.svg") no-repeat;
background-position: top right -170px;
text-align: center;
}
.neutral-grey-100 {
color: var(--neutral-grey-100);
}
.neutral-grey-300 {
color: var(--neutral-grey-300);
}
.neutral-grey-600 {
color: var(--neutral-grey-600);
}
.neutral-grey-900 {
color: var(--neutral-grey-900);
}
h1 {
font-size: 2em;
margin-bottom: .8em;
}
h2 {
font-size: 3em;
margin: 1rem 0;
}
.container {
width: 85%;
margin: 0 auto;
}
.header {
padding: 2.4em;
}
.card {
display: flex;
flex-direction: column;
background-color: var(--neutral-100);
border-radius: .8em;
padding: 1em 2.6em;
margin-bottom: 2.5em;
box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
}
.card:nth-child(odd) {
background: var(--gradient);
color: var(--neutral-100);
}
.card > div:not(:last-child) {
border-bottom: 1px solid rgba(183, 184, 194, 0.45);
}
.card-inverse > div:not(:last-child) {
border-bottom: 1px solid rgba(255, 255, 255, 0.35);
}
section div {
padding: 1em 0;
}
.button {
text-transform: uppercase;
padding: 1em 2em;
margin: 2.6em 0 1.2em 0;
background: var(--gradient);
border: 1px solid var(--neutral-100);
border-radius: 6px;
text-decoration: none;
color: var(--neutral-100);
}
.button:hover, .button:focus {
background: var(--neutral-100);
border: 1px solid hsl(237, 63%, 24%);
color: var(--gradient-900);
outline: none;
}
.button-inverse {
background: var(--neutral-100);
text-decoration: none;
color: var(--gradient-900);
}
.button-inverse:hover, .button-inverse:focus {
background: hsl(237, 63%, 64%);
border: 1px solid var(--neutral-100);
color: var(--neutral-100);
outline: none;
}
.attribution {
font-size: 11px;
text-align: center;
margin-bottom: 1rem;
}
.attribution a {
color: hsl(228, 45%, 44%);
}
/*-------- TOGGLER --------*/
.toggle {
display: flex;
justify-content: center;
align-items: center;
}
input[type=checkbox]{
height: 0;
width: 0;
visibility: hidden;
}
label {
cursor: pointer;
text-indent: -9999px;
width: 65px;
height: 35px;
background: var(--gradient);
display: block;
border-radius: 100px;
position: relative;
margin: 1.4em;
}
label:after {
content: '';
position: absolute;
top: 4px;
left: 4px;
width: 27px;
height: 27px;
background: #fff;
border-radius: 110px;
-webkit-transition: all 350ms;
-moz-transition: all 350ms;
transition: all 350ms;
}
input:checked + label {
background: var(--gradient);
}
input + label:hover, input + label:focus-within {
background: hsl(236, 72%, 81%)
}
input:checked + label:after {
transform: translate3d(114%, 0, 0);
}
#media (min-width: 1440px) {
body {
font-size: 16px;
background-image: url("../images/bg-top.svg"), url("../images/bg-bottom.svg");
background-repeat: no-repeat, no-repeat;
background-position: 100% 0%, 0% 130%;
background-size: 24%, 24%;
}
.container {
display: grid;
grid-template-areas:
"header header header"
"basic professional master"
"attribution attribution attribution";
align-items: center;
width: 65%;
}
.header {
grid-area: header;
}
h2 {
font-size: 4em;
}
h3 {
font-size: 1.3033333333333335em;
}
.card-inverse {
padding: 3em 2em;
}
.card {
margin-bottom: 0;
}
#basic {
grid-area: basic;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
#professional {
grid-area: professional;
}
#master {
grid-area: master;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.attribution {
grid-area: attribution;
margin-top: 4em;
}
}
<div class="container">
<section class="header">
<h1 class="neutral-grey-900">Our Pricing</h1>
<div class="toggle neutral-grey-300">
Annually
<input type="checkbox" id="switch"/><label for="switch">Toggle</label>
<!-- <label class="switch"><input type="checkbox" name="toggler" id="toggler" onClick="refreshPage()"/> <figure></figure>
</label> -->
Monthly
</div>
</section>
<section class="card" id="basic">
<div>
<h3 class="neutral-grey-600">Basic</h3>
<h2 class="neutral-grey-900 monthly">$19.99</h2>
<h2 class="neutral-grey-900 annual">$199.99</h2>
</div>
<div class="neutral-grey-600">500 GB Storage</div>
<div class="neutral-grey-600">2 Users Allowed</div>
<div class="neutral-grey-600">Send up to 3 GB</div>
<a class="button button-main" href="">Learn More</a>
</section>
<section class="card card-inverse" id="professional">
<div>
<h3>Professional</h3>
<h2 class="monthly">$24.99</h2>
<h2 class="annual">$249.99</h2>
</div>
<div>1 TB Storage</div>
<div>5 Users Allowed</div>
<div>Send up to 10 GB</div>
<a class="button button-inverse" href="">Learn More</a>
</section>
<section class="card" id="master">
<div>
<h3 class="neutral-grey-600">Master</h3>
<h2 class="neutral-grey-900 monthly">$39.99</h2>
<h2 class="neutral-grey-900 annual">$399.99</h2>
</div>
<div class="neutral-grey-600">2 TB Storage</div>
<div class="neutral-grey-600">10 Users Allowed</div>
<div class="neutral-grey-600">Send up to 20 GB</div>
<a class="button button-main" href="">Learn More</a>
</section>
<div class="attribution">
Challenge by Frontend Mentor.
Coded by Sachin Jadhav.
</div>
</div>
If you want to remember the setting for future visits, store it in localStorage and use it when loading the page:
const updatePriceDisplay = () => {
document.body.classList.toggle("show-monthly", toggler.checked);
};
toggler.checked = localStorage.getItem("show-monthly") === "Y";
updatePriceDisplay();
toggler.addEventListener("click", () => {
updatePriceDisplay();
localStorage.setItem("show-monthly", toggler.checked ? "Y" : "N");
});
You set onClick="refreshPage()" on your switch. So the page always reloads when someone tries to change its value (en-/disable it).
The default behavior of chrome is to loose/forget all the data that was entered before a reload for a formular, while firefox normally asks (or if the user wants it without a popup, defaults) to reenter all the data the user entered after the reload.
Thats why the reload is resetting the value in chrome and keeping it in firefox.
I would recommend to just not reload the page. That also brings better usablity.
<!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">
<title>Preview Testing</title>
</head>
<body>
<style>
.buttonDownload {
display: inline-block;
position: relative;
padding: 10px 25px;
background-color: #1d71ff;
color: white;
font-family: sans-serif;
text-decoration: none;
font-size: 0.9em;
text-align: center;
text-indent: 15px;
margin: 2px;
border-radius: 12px;
align-items: center;
}
.down-button{
width: 100%;
text-align: center;
}
.buttonDownload:hover {
background-color: #333;
color: white;
}
.buttonDownload:before, .buttonDownload:after {
content: ' ';
display: block;
position: absolute;
left: 15px;
top: 52%;
}
/* Download box shape */
.buttonDownload:before {
width: 15px;
height: 2px;
border-style: solid;
border-width: 0 2px 2px;
}
/* Download arrow shape */
.buttonDownload:after {
width: 0px;
height: 0px;
margin-left: 3px;
margin-top: -7px;
border-style: solid;
border-width: 4px 4px 0 4px;
border-color: transparent;
border-top-color: inherit;
animation: downloadArrow 2s linear infinite;
animation-play-state: paused;
}
.buttonDownload:hover:before {
border-color: #4CC713;
}
.buttonDownload:hover:after {
border-top-color: #4CC713;
animation-play-state: running;
}
.milkparagraph{
color: #FF4500;
font-size: 19px;
margin: 15px;
}
.milkdownbox{
border: 2px solid #365194;
padding: 0px 5% 7px 2%;
border-radius: 12px;
margin: 17px 0% 20px;
width: fit-content;
}
/* keyframes for the download icon anim */
#keyframes downloadArrow {
/* 0% and 0.001% keyframes used as a hackish way of having the button frozen on a nice looking frame by default */
0% {
margin-top: -7px;
opacity: 1;
}
0.001% {
margin-top: -15px;
opacity: 0;
}
50% {
opacity: 1;
}
100% {
margin-top: 0;
opacity: 0;
}
}
</style>
<div class="syltp">
<script type="text/javascript">
$(function(){
$('#button').click(function(){
if(!$('#iframe').length) {
$('#iframeHolder').html('<iframe id="iframe" src="https://drive.google.com/file/d/1GEsC2NXwLjvV4N2JCPqAqAxqMEt3uro0/preview" width="700" height="400" style="border: 1px solid black;"></iframe>');
}
});
});
</script>
<h4> <span style="font-family: 'Open Sans';"><i aria-hidden="true" class="fa fa-sticky-note"></i>Preview without jquery</span></h4>
<div class="down-button" id="button"><b class="buttonDownload">PREVIEW</b></div>
<br />
<div id="iframeHolder"></div>
</div>
</body>
</html>
How to open iframe only on when the button is clicked without using jquery <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js' type='text/javascript'></script>
here when we open a website the iframe should not load it should load only when the button is clicked
My present code :
<!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">
<title>Preview Testing</title>
</head>
<body>
<style>
.buttonDownload {
display: inline-block;
position: relative;
padding: 10px 25px;
background-color: #1d71ff;
color: white;
font-family: sans-serif;
text-decoration: none;
font-size: 0.9em;
text-align: center;
text-indent: 15px;
margin: 2px;
border-radius: 12px;
align-items: center;
}
.down-button{
width: 100%;
text-align: center;
}
.buttonDownload:hover {
background-color: #333;
color: white;
}
.buttonDownload:before, .buttonDownload:after {
content: ' ';
display: block;
position: absolute;
left: 15px;
top: 52%;
}
/* Download box shape */
.buttonDownload:before {
width: 15px;
height: 2px;
border-style: solid;
border-width: 0 2px 2px;
}
/* Download arrow shape */
.buttonDownload:after {
width: 0px;
height: 0px;
margin-left: 3px;
margin-top: -7px;
border-style: solid;
border-width: 4px 4px 0 4px;
border-color: transparent;
border-top-color: inherit;
animation: downloadArrow 2s linear infinite;
animation-play-state: paused;
}
.buttonDownload:hover:before {
border-color: #4CC713;
}
.buttonDownload:hover:after {
border-top-color: #4CC713;
animation-play-state: running;
}
.milkparagraph{
color: #FF4500;
font-size: 19px;
margin: 15px;
}
.milkdownbox{
border: 2px solid #365194;
padding: 0px 5% 7px 2%;
border-radius: 12px;
margin: 17px 0% 20px;
width: fit-content;
}
/* keyframes for the download icon anim */
#keyframes downloadArrow {
/* 0% and 0.001% keyframes used as a hackish way of having the button frozen on a nice looking frame by default */
0% {
margin-top: -7px;
opacity: 1;
}
0.001% {
margin-top: -15px;
opacity: 0;
}
50% {
opacity: 1;
}
100% {
margin-top: 0;
opacity: 0;
}
}
</style>
<div class="syltp">
<script type="text/javascript">
$(function(){
$('#button').click(function(){
if(!$('#iframe').length) {
$('#iframeHolder').html('<iframe id="iframe" src="https://drive.google.com/file/d/1GEsC2NXwLjvV4N2JCPqAqAxqMEt3uro0/preview" width="700" height="400" style="border: 1px solid black;"></iframe>');
}
});
});
</script>
<h4> <span style="font-family: 'Open Sans';"><i aria-hidden="true" class="fa fa-sticky-note"></i>Preview without jquery</span></h4>
<div class="down-button" id="button"><b class="buttonDownload">PREVIEW</b></div>
<br />
<div id="iframeHolder"></div>
</div>
</body>
</html>
it is my present code if I add the above-mentioned jquery its works fine but here I removed it now it's not working
so I want to work it without jquery
That sticky sidebar should auto-scroll with the main content but when I used to frame the sidebar not scrolling down. It also block my comment frame
Check this, Is this what do you need?
const btn = document.querySelector("button.openIframe");
const frame = document.getElementById("frame");
btn.addEventListener("click", toggleIframe);
function toggleIframe(){
var src = "https://www.jqueryscript.net/";
frame.classList.toggle("d-none");
btn.classList.toggle("opened");
if(btn.classList.contains("opened")){
btn.innerHTML = "Close IFrame";
src = prompt("Enter a Source :", "https://www.jqueryscript.net/");
}
else{
btn.innerHTML = "Open IFrame";
}
frame.src = src;
}
.d-none{ display:none; }
<button class="openIframe">Open IFrame</button>
<iframe id=frame class="d-none" width="100%" height="60%">
</iframe>
Or Same in a Better Way ( Update )
const btn = document.querySelector("#load");
const src = document.querySelector("#src");
const frame = document.querySelector("#frame");
btn.addEventListener("click", toggleFrame);
function toggleFrame(){
frame.src = "about:blank";
if(src.value !== null){
src.classList.toggle("d-none");
btn.classList.toggle("opened");
frame.src = src.value;
frame.classList.toggle("d-none");
if(btn.classList.contains("opened"))
btn.innerHTML = "Close";
else
btn.innerHTML = "Load";
}
}
.d-none{ display:none; }
<input id=src placeholder="Enter a SRC" value="https://www.jqueryscript.net/"><button id=load>Load</button>
<iframe id=frame class=d-none width="100%"></iframe>
iFrame
I want to create a menu for one page site but I'm not very good at JavaScript and I have this code for open and close the menu but I want it to open like with a easy transition because but it just appear.
How can I add fade-in-out or something like that:
<script>
function w3_open() {
document.getElementById("mySidebar").style.visibility = "visible";
}
function w3_close() {
document.getElementById("mySidebar").style.visibility = "hidden";
}
</script>
w3-button{
position:fixed;
width: 42px;
height: 42px;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
line-height:1.1;
text-align:center;
top:6.5px;
left: 8px;
background-color: #f2bd66;
z-index:11;
background-position:center;
cursor: pointer;
color: white;
margin-top: 0.7%;
margin-left: 0.7%;
}
.w3-button{
width: 42px;
height: 42px;
margin-top: 0.7%;
margin-left: 0.7%;
}
.w3-button::before {
content:"☰";
font-size:32px;
color:white;
text-align: center;
}
.w3-button:hover{
opacity: 0.6;
}
.w3-sidebar {
position: absolute;
z-index:12;
width:188px;
left: -188px;
line-height:2;
position:fixed;
border-bottom:.5px solid rgba(204, 158, 90, 1);
border-top:.5px solid rgba(204, 158, 90, 1);
background-color:#f2bd66;
font-family: 'Libre Baskerville', serif;
font-weight: 400;
text-align:center;
color: #5b5f5e;
height: 100vh;
border-right:4px solid #af874b;
}
.w3-bar-item {
width: 188px;
margin:0 auto;
line-height:2;
border-bottom:.5px solid rgba(204, 158, 90, 1);
border-top:.5px solid rgba(204, 158, 90, 1);
background-color:transparent;
font-family: 'Libre Baskerville', serif;
font-weight: 400;
text-align:center;
color: #5b5f5e;
float: left;
}
#close-menu{
background-color: #5b5f5e;
color: white;
}
#close-menu:hover{
opacity: 0.7;
}
.nav a:hover {
background-color: #292446;opacity: 0.9;
color: white;
}
<div class="w3-sidebar " style="visibility:hidden" id="mySidebar" >
<button onclick="w3_close()" class="w3-bar-item w3-large" id="close-menu"> Close ×</button>
<nav class="nav">
Inicio
Sobre mí
Galería
Booktubers GT
Recursos E-stela
Redes Sociales
</nav>
</div>
<div class="w3-teal">
<button class="w3-button" onclick="w3_open()"></button>
</div>
If you don't know how to do that in js, you can make it in pure css :
Toggle class on HTML element without jQuery
If you still want to use js to achive that, you can toggle a class on your menu container when the button is clicked, and make transition with css based on the toggled class. If you use jquery you can do that with simple jquery fade or slide function :
<script>
$('#my-menu-button').click(function(){
$('#my-menu').slideToggle();
})
</script>
I wrote a demo for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo</title>
<style>
.test {
width: 100px;
height: 100px;
background: #000;
display: block;
transition: 1s;
opacity: 0
}
.active {
opacity: 1
}
</style>
</head>
<body>
<div class="test"></div>
<button onclick="show()">show</button>
<button onclick="hide()">hide</button>
<script>
var test = document.querySelector('.test')
function show () {
test.className = 'test active'
}
function hide () {
test.className = 'test'
}
</script>
</body>
</html>