i really need help with a memory-style game that i have to create for a school project. The issue right now is that my if statements wont really work properly. i want to compare cards and then if they match they should stay open and the score should go up, and if they don't match they should close again. but right now it says the first card click is right and anything clicked on after that is wrong
//Function for the dropdown content
function dropdownTips() {
document.getElementById("mydropdown").classList.toggle("show");
}
window.addEventListener("click", function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdowncontent");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
var score = 0;
var firstClick = null;
var secondoClick = null;
const cards = document.getElementsByClassName("card");
window.addEventListener("click", (event) => {
for (let i = 0; i < cards.length; i++) {
cards[i].addEventListener("click", function() {
cards[i].classList.add("open");
})};
let clicked = event.target.dataset.type;
if(firstClick == null){
firstClick = clicked
} else {
secondoClick = clicked
}
if(secondoClick == firstClick){
console.log('same click')
score++;
firstClick = null;
secondoClick = null;
} else if(secondoClick != null && firstClick != secondoClick) {
console.log('metti null')
firstClick = null;
secondoClick = null;
}});
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
header {
background-color:#00005e;
height: 60px;
position: relative;
}
header h1 {
color: white;
position: absolute;
top: 17%;
left: 39%;
right: 40%;
width: 355px;
}
/*The 'tips?' button and the drop down content*/
header button {
display: inline-flex;
position:absolute;
align-items: center;
right: 2%;
top: 15%;
bottom: 15%;
padding: 10px 20px;
font-size: 20px;
background-color:white;
color: #00005e;
border-radius: 10px;
cursor: pointer;
border-color: transparent;
}
header button:hover {
opacity: 80%;
}
.dropdowncontent {
display: none;
position: absolute;
right: 0%;
top: 100%;
background-color:#00005e;
min-width: 160px;
max-width: 400px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
border-bottom-left-radius: 20px;
z-index: 100;
}
.dropdowncontent li {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.advise{
font-size: 19px;
}
.passwordtips {
font-size: 30px;
left: 20%;
}
.show {
display:block;
}
/*The link in the dropdowncontent*/
a {
text-decoration: underline;
color: white;
}
a:hover {
cursor: pointer;
}
/*The score counter*/
.score {
color: #01016e;
display: flex;
justify-content: center;
margin: 20px;
}
/*The game section*/
section {
max-width: 1300px;
height: 550px;
display: flex;
justify-content: space-around;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
border-radius: 7px;
border-color: #00005e;
border-style: solid;
border-width: 5px;
position: relative;
}
/*The sections content*/
.wrapper {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 185px;
margin-top: 7px;
}
.card{
background-color: #01016e;
color: white;
margin: 10px 10px;
height: 150px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
border-radius: 5px;
}
.card h2{
padding: 2px;
transform: scale(-1,1);
}
.card:hover {
cursor: pointer;
}
.open{
animation: flip .5s;
animation-fill-mode: forwards;
transform-style: preserve-3d;
}
#keyframes flip {
from {
background: #00005e;
font-size: 0;
}
to{
background: rgb(20, 73, 185);
font-size:17px;
transform: rotateY( 180deg );
}
}
/* .welcome {
display: flex;
justify-content: center;
text-align: center;
color: #3c3b6e;
margin-top: 100px;
font-size: 50px;
clear: both;
position: absolute;
}
.startbutton {
display: flex;
justify-content: center;
align-self: center;
margin-top: 100px;
position: absolute;
background-color: #00005e;
color: #e8ebf1;
padding: 10px;
font-size: 30px;
border-radius: 4px;
z-index: 0;
border-color: transparent;
}
.startbutton:hover{
cursor: pointer;
background-color: #3c3b6e;
}
*/
/*The game*/
/*The 'DID YOU KNOW' over the ticker*/
.facts {
display: flex;
justify-content: space-around;
margin-top: 30px;
font-size: 20px;
color: #00005e;
}
/*The facts ticker*/
.tcontainer {
max-width: 1200px;
margin-top: 20px;
overflow: hidden;
margin-left: auto;
margin-right: auto;
border-radius: 5px;
z-index: 1000;
}
.ticker-wrap {
width: 100%;
padding-left: 100%;
background-color: #00005e;
}
#keyframes ticker {
0% { transform: translate3d(0, 0, 0); }
100% { transform: translate3d(-100%, 0, 0); }
}
.ticker-move {
display: inline-block;
white-space: nowrap;
padding-right: 100%;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: ticker;
animation-duration: 55s;
}
.ticker-move:hover{
animation-play-state: paused;
}
.ticker-item{
display: inline-block;
padding-top: 5px;
padding-bottom: 2px;
padding-right: 3em;
color: white;
min-height: 40px;
font-size: 25px;
}
/*The pause button for the ticker*/
.pause {
display: flex;
justify-content: center;
margin-top: 10px;
}
.pausebutton {
padding: 5px;
border-radius: 3px;
background-color: #00005e;
color: white;
border-style: none;
cursor: pointer;
}
.pausebutton:hover {
background-color: #3c3b6e;
}
<!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="css/style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght#700&display=swap" rel="stylesheet">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<title>The Password Game</title>
</head>
<body>
<header>
<h1>THE PASSWORD GAME</h1>
<div class="dropdown">
<button onclick="dropdownTips()" class="dropbtn">TIPS?</button>
<div class="dropdowncontent" id="mydropdown" >
<ul>
<li class="passwordtips">Tips for making strong passwords: </li>
<li class="advise">1. Use 16 characters or more (use both uppercase and lowercase letters, number and symbols.)</li>
<li class="advise">2. Never use the same password twice.</li>
<li class="advise">3. Use a password manager.</li>
<li class="advise">4. Don't write your passwords down on paper.</li>
<li class="advise">5. Don't share your passwords with others.</li>
<li class="advise">6. Change your password after a breach.</li>
<li class="advise">7. Sign up for data breach notifications. (like haveibeenpwned.com).</li>
<li class="advise">8. Check your accounts regularly for any suspicious activity. </li>
</ul>
</div>
</div>
</header>
<div class="score"><h2></h2></div>
<section>
<div class="wrapper" id="card-deck">
<div class="card" data-type="1"><h2>What information should you NEVER use in a password?</h2></div>
<div id="answerSix" class="card" data-type="6"><h2>1 log in</h2></div>
<div id="cardThree" class="card" data-type="3"><h2>When should you ALWAYS change your password?</h2></div>
<div id="anserFive" class="card" data-type="5"><h2>suspicious activity</h2></div>
<div id="cardTwo" class="card" data-type="2"><h2>Who is it okay to tell your password to?</h2></div>
<div id="answerFour" class="card" data-type="4"><h2>16</h2></div>
<div id="answerThree" class="card" data-type="3"><h2>After a data breach</h2></div>
<div id="answerTwo" class="card" data-type="2"><h2>No one</h2></div>
<div id="CardSix" class="card" data-type="6"><h2>For how many log ins is it okay to use the same password?</h2></div>
<div id="cardFour" class="card" data-type="4"><h2>How many characters should you AT LEAST use in a password?</h2></div>
<div class="card" data-card="firstSet" data-type="1"><h2>Name and Birthday</h2></div>
<div id="cardFive" class="card" data-type="5"><h2>What should you regularly look for in your accounts?</h2></div>
</div>
</section>
<div class="facts">
<h2>DID YOU KNOW?</h2>
</div>
<div class="tcontainer"><div class="ticker-wrap"><div class="ticker-move">
<div class="ticker-item">There is a hacker attack every 39 seconds.</div>
<div class="ticker-item">90% of passwords can be cracked in less than 6 hours.</div>
<div class="ticker-item">80% of hacking related breaches are linked to insufficient passwords.</div>
<div class="ticker-item">59% use their name or birthday in their password.</div>
<div class="ticker-item">6.850.000 passwords are getting hacked each day.</div>
</div></div></div>
<div class="pause">
<p>Hold your mouse over to pause</p>
</div>
<script src="javascript/javascript.js" ></script>
</body>
</html>
https://codepen.io/anna100d/pen/wvgQLdW
Problems with code can be much easier to understand and solve if they can be simplified first. Here is a stripped-down version of your game that makes it easy to focus on the logic of the click event listener. (Opening a card in this version merely changes its color.)
In the listener, when the first card is clicked, we want to open it and remember it for later.
When the second card is clicked, we open it and compare it to the first card, then we must forget the first card. (If they match, the score changes; if not, we close both cards.)
Edit:
If the two cards don't match, both cards get closed. To let the user see the selected cards while they're both open, you can put the code that closes the cards into a function and pass that function to JavaScript's built-in setTimeout function.
I updated the snippet to include this behavior (using a couple of additional tricks while I was at it: the "rest" syntax, a "fat arrow" function, and a "closure" -- Search for the respective pages on MDN if you want to learn more about these features.)
// Declares global variables
let score = 0, cardToMatch = null;
// Calls `flipCard` on any click
window.addEventListener("click", flipCard);
// Defines the click listener
function flipCard(event){
// Identifies the card where the click happened
const card = event.target.closest(".card");
// Ignores irrelevant/invalid clicks
if(!card || card.classList.contains("open")){
return;
}
// A valid click always opens the card
card.classList.add("open");
// If this is the 1st card of 2, remember it
if(!cardToMatch){
cardToMatch = card;
}
// If it's the 2nd card, compare types
else{
// If they match...
if(card.dataset.type == cardToMatch.dataset.type){
// ...Increment score and show it in the DOM
updateScoreDisplay(++score);
}
// If they don't...
else{
// ...Flip both cards back over
resetCardsAfterDelay(cardToMatch, card);
}
// Either way, next click will be the 1st of 2
cardToMatch = null;
}
}
function updateScoreDisplay(newScore){
// Syncs the user-displayed value w/ score
const element = document.querySelector(".score span");
element.textContent = newScore;
}
function resetCardsAfterDelay(...listOfCards){
//Takes any number of cards via "rest parameter syntax"
// Uses `setTimeout` to call inner `resetAll` func after delay
// Passes our `resetAll` func to `setTimeout` with a delay in milliseconds
const DELAY = 1200;
setTimeout(resetAll, DELAY);
// Inner func (a "closure") knows about `listOfCards`
function resetAll(){
// In a loop, applies a "fat arrow" func to each card
listOfCards.forEach(
(card) => card.classList.remove("open")
)
}
};
*{ margin: 0; padding: 0; }
.header{ margin: 0.3rem; font-size: 1.1rem; }
.score{ margin: 0.3em; font-weight: bold; }
.card{
width: 14em; margin: 0.3em; padding: 0.1em 0.3em;
border-radius: 0.5em; border: 1px solid grey;
}
.open{ background-color: lightskyblue; }
<h1 class="header">The Password Game</h1>
<div class="score">Score: <span>0</span> </div>
<hr/>
<div class="card" data-type="1"> Never use..? (1) </div>
<div class="card" data-type="1"> Name and Birthday (1) </div>
<div class="card" data-type="2"> Tell password to..? (2) </div>
<div class="card" data-type="2"> No one (2) </div>
<div class="card" data-type="3"> Always change PW..? (3) </div>
<div class="card" data-type="3"> After a data breach (3) </div>
Related
The problem is with a sliding-up footer, which is triggered by clicking on an up-arrow. The footer is positioned inside of the page-wrap(as everything is), and instead of sliding up/appearing inside of the page-wrap container as it should, it slides-up on top of it. The page-wrap container acts as a frame with rounded corners for the whole content of the page/website and all body elements are supposed to be inserted inside of it.
I tried several approaches to resolve the issue, including rearranging the HTML elements, adjusting the z-index values in the CSS, and tweaking the JavaScript code, but none of these efforts produced the desired result. I was expecting the footer to slide up inside the page-wrap container and not be positioned on top of everything.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Helvetica+Neue&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css" type="text/css">
<title>Retro Step</title>
</head>
<body>
<div class="page-wrap">
<footer class="slide-up-footer">
<div class="footer-text">
<p>FREE SHIPPING IN PORTUGAL / IN EUROPE FROM 150€ / EASY RETURNS</p>
</div>
<div class="footer-text2">
ABOUTTERMSPRIVACYCOOKIE SETTINGSSUPPORT
</div>
<div class="sign-up-promos">
<div id="info-text"></div>
<form id="newsletter-form" action="your-newsletter-signup-action" method="post" novalidate>
<input type="email" name="email" placeholder="Sign up for exclusive promos, popular releases & more" id="email-input" onfocus="displayInfo(), displaySecondInfo()" type="submit">
</form>
<div id="info-text2"></div>
</div>
<div class="footer-creds">
© GRUPO 15, 2023. ALL RIGHTS RESERVED. TW / TSIW
</div>
</footer>
<div class="up-arrow" id="up-arrow">
<span class="custom-class">^</span>
</div>
<script src="script.js"></script>
</div>
</body>
</html>
html {
scroll-behavior:smooth;
}
body {
font-family: 'Adobe Caslon Pro Bold', sans-serif;
background-color: red;
overflow: hidden;
}
body h1 {
text-align: center;
}
.page-wrap {
position: fixed;
top: 10px;
right: 10px;
left: 10px;
bottom: 10px;
background: white;
border-radius: 30px;
padding: 20px;
text-align: center;
overflow: hidden;
}
.page-wrap h1 {
margin: 0;
}
p {
line-height: 3;
}
::-webkit-scrollbar-track {
background: none;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 5px;
}
.slide-up-footer {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
font: 9px SuisseIntl-Regular, sans-serif;
position: fixed;
bottom: -1000px; /* or another value that will hide the footer */
width: 100vw;
height: 15%;
transition: all 0.7s ease-in-out;
background-color: white;
}
.slide-up-footer.show {
top: 500px;
}
.footer-text {
display: grid;
grid-row: 1/2;
font: 9px SuisseIntl-Regular, sans-serif;
color: black;
text-align: center;
padding: 10px;
justify-content: center;
position: relative;
display: grid;
}
.footer-text2 {
font: 9px SuisseIntl-Regular, sans-serif;
grid-row: 2/3;
color: black;
text-align: top;
padding: 10px;
}
.footer-text2 a{
text-decoration: none;
color: black;
margin: 0px 10px;
}
.footer-text2 a:hover{
text-decoration: underline;
color: black;
}
.footer-creds {
font: 9px SuisseIntl-Regular, sans-serif;
position: relative;
display: grid;
grid-row: 3/4;
color: black;
text-align: top;
padding: 10px;
margin: 0px 10px;
align-items: end;
}
.up-arrow {
transition: all 0.7s ease-in-out;
position: absolute;
bottom: 0px;
right: 0px;
margin: 2rem;
z-index: 999;
}
.custom-class{
font-weight: bold;
font: 20px SuisseIntl-Regular, sans-serif;
color:black;
cursor: pointer;
z-index: 999;
}
.sign-up-promos {
display: grid;
position: absolute;
justify-content: flex-end;
grid-row: 2/3;
grid-template-rows: 1fr 1fr 1fr ;
flex-wrap: wrap;
padding: 10px;
color: black;
float: right;
right: 20px;
}
.sign-up-promos form {
display: grid;
align-items: center;
grid-row: 2/3;
background: transparent;
border-bottom: 2px solid black;
}
.sign-up-promos label {
margin-right: 10px;
}
.sign-up-promos input {
text-align: left;
border: none;
background: transparent;
font: 10px SuisseIntl-Regular, sans-serif;
color: black;
padding: 5px;
width: 270px;
}
.sign-up-promos input::placeholder {
font: 10px SuisseIntl-Regular, sans-serif;
color: black;
}
#email-input:focus {
outline: none;
background: transparent;
}
.sign-up-promos input:focus {
outline: none;
background: transparent;
}
input:-webkit-autofill {
background-color: transparent !important;
}
#info-text {
display: grid;
text-transform: uppercase;
grid-row: 1/2;
align-items: flex-end;
transition: visibility 0.5s ease-in-out;
}
#info-text2 {
width: 270px; /* or any other value you prefer */
display: grid;
grid-row: 3/4;
align-items: center;
transition: visibility 0.5s ease-in-out;
}
#info-text.visible {
visibility: visible;
transform: translateY(-5px);
transition: visibility 0.5s, transform 0.5s ease-in-out;
}
#info-text2.visible {
visibility: visible;
transform: translateY(10px);
transition: visibility 0.5s, transform 0.5s ease-in-out;
}
// Get the up arrow element
const upArrow = document.getElementById("up-arrow");
const footer = document.querySelector(".slide-up-footer");
let isOpen = false;
// Add an event listener to toggle the "show" class
upArrow.addEventListener("click", toggleFooter);
function toggleFooter() {
if (isOpen) {
footer.style.bottom = "-100%";
upArrow.style.transform = "rotate(0deg)";
upArrow.style.bottom = "0";
} else {
footer.style.bottom = "0";
upArrow.style.bottom = "12%";
upArrow.style.transform = "rotate(180deg)";
}
isOpen = !isOpen;
}
function displayInfo() {
document.getElementById("info-text").innerHTML = "Enter email:";
document.getElementById("info-text").classList.add("visible")
}
function displaySecondInfo() {
document.getElementById("info-text2").innerHTML = "By signing up, you confirm you are over 16 years of age and you want to receive GOAT emails. Please see our Terms & Conditions and Privacy Policy for more details.";
document.getElementById("info-text2").classList.add("visible")
}
function validateEmail(email) {
var re = /^\S+#\S+.\S+$/;
return re.test(String(email).toLowerCase());
}
document.getElementById("newsletter-form").addEventListener("submit", function(event) {
event.preventDefault();
var emailInput = document.getElementById("email-input");
if (!validateEmail(emailInput.value)) {
// display an error message
document.getElementById("info-text2").innerHTML = "Please enter a valid email address.";
setTimeout(function() {
document.getElementById("email-input").value = "";
document.getElementById("info-text2").innerHTML = "By signing up, you confirm you are over 16 years of age and you want to receive GOAT emails. Please see our Terms & Conditions and Privacy Policy for more details.";
}, 1000);
} else {
// update the text of info-text
document.getElementById("info-text").innerHTML = "Thank you for subscribing!";
document.getElementById("info-text2").innerHTML = "";
document.getElementById("info-text").classList.add("submited");
setTimeout(function() {
document.getElementById("info-text").innerHTML = "Enter email:";
document.getElementById("info-text2").innerHTML = "By signing up, you confirm you are over 16 years of age and you want to receive GOAT emails. Please see our Terms & Conditions and Privacy Policy for more details.";
document.getElementById("info-text").classList.remove("submited");
emailInput.value = '';
}, 1500);
}
});
let slideUpFooter = document.querySelector(".slide-up-footer");
let infoText = document.getElementById("info-text");
let infoText2 = document.getElementById("info-text2");
let observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (!entry.isIntersecting) {
// footer is not in view, reset form
document.getElementById("email-input").value = "";
document.getElementById("info-text").innerHTML = "";
document.getElementById("info-text2").innerHTML = "";
infoText.removeAttribute("class");
infoText2.removeAttribute("class");
}
});
});
observer.observe(slideUpFooter);
document.getElementById("email-input").addEventListener("input", function(event) {
// check if the email input is empty
if (event.target.value.trim() === "") {
// display the original messages
document.getElementById("info-text").innerHTML = "Enter email:";
document.getElementById("info-text2").innerHTML = "By signing up, you confirm you are over 16 years of age and you want to receive GOAT emails. Please see our Terms & Conditions and Privacy Policy for more details.";
document.getElementById("info-text").classList.remove("submited");
}
});
I added a fixed position to the page-wrap element and set its top, right, left, and bottom properties to 10 pixels each. This positions the element in the center of the page. I also set a white background and a border radius of 30 pixels to create the rounded border.
Finally, I added a button to the page and some other components.
This allows you to test the appearance of the rounded border with additional elements on the page.
I hope this helps! Let me know if you have any questions.
I was able to create a page with a rounded inside body border by using the following code:
body {
background: #5bb0ff;
}
.page-wrap {
position: fixed;
top: 10px;
right: 10px;
left: 10px;
bottom: 10px;
background: white;
border-radius: 30px;
padding: 20px;
text-align: center;
overflow-y: scroll;
}
.page-wrap h1 {
margin: 0;
}
p {
line-height: 3;
}
::-webkit-scrollbar-track {
background: none;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 5px;
}
.texture-overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-repeat: repeat;
background-image: url("images/texture.png");
mix-blend-mode: multiply;
pointer-events: none;
width: 100%;
height: 100%;
opacity: 0.5;
transform: translateZ(1px);
z-index:2
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Helvetica+Neue&display=swap" rel="stylesheet">
<link rel="stylesheet" href="teststyle.css" type="text/css">
<title>Retro Step</title>
</head>
<body>
<div class="page-wrap">
<h1>Rounded inside body border</h1>
<button>Add text</button>
</div>
<div class="texture-overlay"></div>
</body>
</html>
const footer = document.querySelector(".slide-up-footer");
.slide-up-footer {
display: grid;
position: fixed;
bottom: -1000px; /* or another value that will hide the footer */
width: 100vw;
...
The problem your script is applying the slide-up effect directly to the footer. In that moment footer is "detached" from the container .page-wrap
You should modify your script to apply the slide-up effect (adding a new class) directly to the .page-wrap-footer
or you need to apply the style and rounded borders directly to footer, removing it from the .page-wrap parent.
I want to make an weather app and I want to let the user to add in the application some weather cards with the city they are interested with. If they no longer want a specific weather card, they can delete it. For now, you can add some empty cards by using the + button.
Below is what I did and how the app looks like.
In the first phase I want the displayed cards to show the city weather information at the current time and with a hover I want the card to expand and display more information about that city such as a 5 day forecast.
I don't know how to stretch a specific card on hover and I'm asking your help with this problem. Thank you!
const displayContent = document.querySelector('.content');
const widget = document.querySelector('.widget');
const addWidget = document.querySelector(".addButton");
console.log(displayContent)
addWidget.addEventListener('click', newWidget);
var cont=0;
function newWidget(){
cont=cont+1;
let newWidget = document.createElement('div');
newWidget.setAttribute('class', 'widget');
newWidget.setAttribute('id', "widget" + cont);
let closeBtn = document.createElement('span');
closeBtn.setAttribute('class', 'remove');
closeBtn.setAttribute('id', 'remove' +cont);
closeBtn.textContent = '✕';
displayContent.appendChild(newWidget);
newWidget.appendChild(closeBtn);
//remove the cards
var close = document.querySelectorAll("span");
for(let i=0 ; i<close.length; i++){
close[i].addEventListener('click', () =>{
close[i].parentElement.remove();
})
}
}
#import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght#0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
:root {
--fontcolor: #313131;
--bgcolor: #FAFAFA;
}
html {
font-family: "Roboto", sans-serif;
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bgcolor);
margin: 0;
color: var(--fontcolor);
transition: background-color 500ms cubic-bezier(0.075, 0.82, 0.165, 1);
}
.container {
max-width: 85vw;
margin: 0 auto;
}
header {
display: flex;
margin-bottom: 30px;
font-size: 1.5em;
align-items: center;
justify-content: space-between;
}
.search {
width: 100%;
position: relative;
display: flex;
}
.searchTerm {
width: 100%;
border: 3px solid black;
border-right: none;
padding: 5px;
height: 20px;
border-radius: 5px 0 0 5px;
outline: none;
}
.addButton {
width: 40px;
height: 36px;
border: 1px solid black;
background: black;
text-align: center;
color: #fff;
border-radius: 0 6px 5px 0;
cursor: pointer;
font-size: 20px;
}
.content {
margin-bottom: 1em;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-auto-rows: minmax(250px, 1fr);
grid-gap: 25px;
}
.widget {
color: white;
display: flex;
flex-direction: column;
padding: 25px;
position: relative;
white-space: normal;
word-wrap: break-word;
transition: background-color 50ms;
background: linear-gradient(130deg, rgba(25,118,210,1) 0%, rgba(63,81,181,1) 100%);
box-shadow: 5px 5px 18px -1px rgb(0 0 0 / 34%);
border-radius: 5px;
}
.remove{
position: absolute;
top: 5px;
right: 12px;
font-size: 22px;
opacity: 0.7;
cursor: pointer;
}
#keyframes append-animate {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0%);
opacity: 1;
}
}
/* animate new box */
.widget {
animation: append-animate .3s linear;
}
<!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>My Library</title>
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/31c84a9fec.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<header class="header">
<h1 id='title'>Weather App</h1>
<div class="control">
<div class="wrap">
<div class="search">
<input type="text" class="searchTerm" placeholder="Add a city">
<button type="submit" class="addButton">+</button>
</div>
</div>
</div>
</header>
<div class="content">
<div class="widget" id="widget0">
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Have you tried using CSS transitions?
div {
width: 100px;
height: 100px;
background-color: blue;
margin: 10px;
transition: all 1s;
}
div.h:hover {
width: 150px;
background-color: purple;
}
div.v:hover {
height: 150px;
background-color: purple;
}
<div class="h"></div>
<div class="v"></div>
window.addEventListener for scroll event is not working in my JS. I've tried several ways but still not working. I've used intersectionObserver in the JS also. Here is the JS code
const moveToAbout = () => {
document.getElementById('about').scrollIntoView(true)
}
const moveToWork = () => {
document.getElementById('work').scrollIntoView()
}
const moveToTop = () => {
document.getElementById('main-section').scrollIntoView(true)
}
const options = {
root: null,
threshold: 0,
rootMargin: "-150px"
}
const header = document.querySelector("header")
const sections = document.querySelectorAll(".section")
const mainSection = document.querySelector(".main-container")
const bttWrapper = document.getElementById('bttBtn-wrapper')
const veganImage = document.getElementById('vegan-store-image')
const navbar = document.getElementById('header')
veganImage.onclick = () => {
window.open("https://thoughtlessmind.github.io/Vegan-store")
}
const sectionOne = document.querySelector(".about-section");
// bttWrapper.style.display = 'none'
const mainObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
header.classList.remove("nav-theme-2")
bttWrapper.classList.add("btnWrapperHidden")
bttWrapper.classList.remove("btnWrapperShow")
} else {
header.classList.add("nav-theme-2")
bttWrapper.classList.add("btnWrapperShow")
}
// console.log(entry.target, '-', entry.isIntersecting)
});
}, options);
mainObserver.observe(mainSection)
window.addEventListener("scroll", (event)=>{
console.log("scrolled")
var scroll = this.scrollY
if(scroll > 20){
console.log('reached')
}
})
const test = () =>{
console.log('working')
}
window.addEventListener("scroll", test)
window.addEventListener("scroll", () => console.log(window.pageYOffset));
Later in the lower part, I've tried to add scroll event in some ways but nothing is happening.
Here is the link for the whole repo: Github repo link
remove height property from CSS main. It is working now :
use min-height, max-height
const moveToAbout = () => {
document.getElementById('about').scrollIntoView(true)
}
const moveToWork = () => {
document.getElementById('work').scrollIntoView()
}
const moveToTop = () => {
document.getElementById('main-section').scrollIntoView(true)
}
const options = {
root: null,
threshold: 0,
rootMargin: "-150px"
}
const header = document.querySelector("header")
const sections = document.querySelectorAll(".section")
const mainSection = document.querySelector(".main-container")
const bttWrapper = document.getElementById('bttBtn-wrapper')
const veganImage = document.getElementById('vegan-store-image')
const navbar = document.getElementById('header')
veganImage.onclick = () => {
window.open("https://thoughtlessmind.github.io/Vegan-store")
}
const sectionOne = document.querySelector(".about-section");
// bttWrapper.style.display = 'none'
const mainObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
header.classList.remove("nav-theme-2")
bttWrapper.classList.add("btnWrapperHidden")
bttWrapper.classList.remove("btnWrapperShow")
} else {
header.classList.add("nav-theme-2")
bttWrapper.classList.add("btnWrapperShow")
}
// console.log(entry.target, '-', entry.isIntersecting)
});
}, options);
mainObserver.observe(mainSection)
window.onload = () =>{
console.log("loaded");
window.onscroll = function()
{
console.log("scrolling.....", window.scrollY);
}
}
#import 'global.css';
/* -----Navigation bar styles */
#import 'navbar.css';
/* ----------- Main contaier styles*/
main{
overflow: scroll;
scroll-snap-type: y mandatory;
}
.section{
/* scroll-snap-align: start; */
/* Uncomment above to add snap scrolling effect */
margin-left: auto;
margin-right: auto;
width: 80%;
max-width: 1100px;
border-bottom: 1px solid grey;
}
.main-container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
}
.name-text{
font-size: 2.8rem;
font-weight: 500;
color: var(--primary-text-color);
}
.intro-text{
padding: 1rem;
padding-left: 0;
font-size: 1.2rem;
color: var(--para-text-color);
}
.right-container{
text-align: left;
}
.text-container{
align-self: center;
}
.left-image{
width: 200px;
height: 200px;
background-color: palegreen;
animation: rotate 8s infinite ease-in-out ;
}
#keyframes rotate{
0%{
border-radius: 0;
}
50%{
border-radius: 50%;
transform: rotate(145deg);
background-color: green;
}
100%{
transform: rotate(360deg);
border-radius: 0;
}
}
.social-link-container{
margin-top: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.social-logo{
font-size: 2rem;
color: var(--primary-text-color);
}
.social-link{
margin: 0 10px;
}
/* About section */
.about-section{
height: 100vh;
padding-top: 38.5px;
border-bottom: 1px solid grey;
}
.about-section > h2{
padding: 10px 10px 10px 0px;
}
/* ----Work section ---- */
#work{
height: 100vh;
padding-top: 38.5px;
}
#work >h2 {
padding: 10px 10px 10px 0;
}
/* .inverse{
background-color: #111;
color: #eee;
} */
.project-card{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10px;
border-radius: 5px;
margin-top: 15px;
transition: 0.3s;
}
.project-card:hover{
background-color: rgba(200, 200, 200, 0.2);
}
.left-side-card{
padding-right: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
max-height: 145px;
height: 145px;
}
.project-name{
margin-bottom: 10px;
display: inline-block;
}
.project-link{
text-decoration: none;
letter-spacing: 0.8px;
position: relative;
}
.project-name::after{
position: absolute;
bottom: 0;
left: 0;
content: '';
height: 1px;
width: 100%;
background-color: black;
/* transform: scale(1); */
transition: 0.3s;
transform-origin: left;
}
.project-name:hover::after{
transform: scale(0);
transform-origin: left;
}
.project-description {
word-spacing: 0.8px;
letter-spacing: -0.2px;
}
.project-image{
height: 150px;
width: 250px;
cursor: pointer;
border-radius: 5px;
}
.tech-stack-container{
display: flex;
}
.tech-stack{
margin-right: 10px;
font-size: 12px;
font-weight: 600;
color: rgba(198, 198, 198,0.8);
transition: 0.3s;
}
.project-card:hover .tech-stack{
color: #6d6d6d
}
.repo-link{
margin-left: 20px;
}
.repo-logo{
color: rgba(0, 0, 0, 0.8);
}
.repo-logo:hover{
color: rgba(0, 0, 0, 0.6);
}
#media only screen and (max-width: 500px){
nav{
display: flex;
align-items: center;
justify-content: center;
float: none;
height: 22px;
}
.section{
width: 90%;
}
.main-container{
flex-direction: column-reverse;
justify-content: space-evenly;
}
.name-text{
text-align: center;
font-size: 28px;
}
.intro-text{
font-size: 18px;
}
.project-card{
flex-direction: column;
}
#work{
min-height: fit-content;
height: fit-content;
}
}
header {
position: fixed;
width: 100%;
background: rgba(255, 255, 255, 0.8);
padding: 10px 0;
z-index: 1;
transition: all ease-in-out 0.5s;
}
.green-nav {
background-color: lawngreen;
}
header:after {
content: "";
display: block;
clear: both;
}
nav {
float: right;
padding: 0 10%;
}
nav a {
font-size: 1rem;
margin: 5px 10px;
color: #484848;
text-decoration: none;
transition: 0.3s;
padding-bottom: 2px;
font-weight: 500;
position: relative;
padding: 2px 5px;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
}
nav a::after {
position: absolute;
bottom: 0;
left: 0;
content: '';
height: 1px;
width: 100%;
background-color: #484848;
transform: scaleX(0);
transition: 0.5s;
transform-origin: center;
}
nav a:hover::after {
transform: scaleX(1);
}
* {
margin: 0;
padding: 0;
scroll-behavior: smooth;
}
:root{
--primary-text-color: #000;
--para-text-color: #323232;
}
body {
font-family: 'Montserrat', sans-serif;
font-weight: 400;
/* scrollbar-color: rgba(0, 0, 0, .5);
scrollbar-track-color: #f1f1f1; */
}
a {
text-decoration: none;
color: #000;
}
/*-------- Custom scroll bar and selection -----*/
#media only screen and (min-width: 600px) {
::-webkit-scrollbar {
width: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(0, 0, 0, .5);
box-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, .6);
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
}
::selection {
background-color: rgb(78, 81, 83);
color: #fff;
}
/* ------- back to top btn */
#bttBtn-wrapper {
position: absolute;
bottom: 50px;
right: 50px;
background-color: grey;
border-radius: 50%;
height: 40px;
width: 40px;
cursor: pointer;
}
.btnWrapperHidden {
transform: scale(0);
transform-origin: center;
transition: 300ms;
}
.btnWrapperShow {
transform: scale(1) rotate(360deg);
transform-origin: center;
transition: 300ms;
}
#bttBtn {
width: 15px;
height: 15px;
border-radius: 2dpx;
border-left: 3px solid;
border-top: 3px solid;
transform: rotate(45deg);
margin: auto;
margin-top: 11px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="google-site-verification" content="x2GVvk7gy3nGrRmARofMXwMNs9MIXvu2BcyEs7RH8KQ" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500,700&display=swap" rel="stylesheet">
<meta name="Description" content="Name: Rajiv, thoughtlessmind, Profession: Web developer, Country: India, ">
<script src="https://kit.fontawesome.com/09ef7cae5b.js" crossorigin="anonymous"></script>
<script defer src="index.js"></script>
<link rel="stylesheet" href="CSS/style.css">
<!-- Chrome, Firefox OS and Opera -->
<meta name="theme-color" content="#4285f4">
<!-- Windows Phone -->
<meta name="msapplication-navbutton-color" content="#4285f4">
<!-- iOS Safari -->
<meta name="apple-mobile-web-app-status-bar-style" content="#4285f4">
<title>Rajiv</title>
</head>
<body>
<div id="top"></div>
<header>
<nav>
<a onclick="moveToWork()">Work</a>
<a onclick="moveToAbout()">About</a>
<a onclick="moveToContact()">Contact</a>
</nav>
</header>
<main>
<div class="main-container section" id="main-section">
<!-- <img src="" alt="avatar" class="avatar" style="height: 200px;width: 200px; background-color: wheat;align-self: center;"> -->
<div class="right-container">
<div class="text-container">
<h1 class="name-text">Rajiv</h1>
<p class="intro-text">
Hey, I'm a web developer based in New Delhi.
<br>
I build things using <b>Javasript</b>.
</p>
</div>
</div>
<div class="left-container">
<div class="left-image">
</div>
<div class="social-link-container">
<a href="https://github.com/thoughtlessmind" target="_blank" id="github" class="social-link">
<i class="fab fa-github social-logo"></i>
</a>
<a href="https://www.linkedin.com/in/thoughtlessmind/" target="_blank" id="linkedin"
class="social-link">
<i class="fab fa-linkedin social-logo"></i>
</svg>
</a>
</div>
</div>
</div>
<!-- Work Section -->
<div id="work" class="work-section section">
<h2>Work</h2>
<div class="project-card">
<div class="left-side-card">
<div>
<a href="https://thoughtlessmind.github.io/Vegan-store" target="_blank" class="project-link">
<h3 class="project-name">
Vegan Store
</h3>
</a>
<p class="project-description">
It is a dummy vegan food store website. <br>
This is a fully responsive website made using CSS Flexbox and Grids
</p>
</div>
<div title="techstack used" class="tech-stack-container">
<p class="tech-stack html-logo">HTML</p>
<p class="tech-stack css-logo">CSS</p>
<a title="open repo" href="" class="repo-link">
<i class="fas fa-code repo-logo"></i>
</a>
</div>
</div>
<div class="right-side-card">
<img src="/assets/vegan-store-img.jpg" title="Visit Page" alt="Vegan store" class="project-image"
id="vegan-store-image">
</div>
</div>
<div class="project-card">
<div class="left-side-card">
<div>
<a href="https://thoughtlessmind.github.io/Vegan-store" target="_blank" class="project-link">
<h3 class="project-name">
Vegan Store
</h3>
</a>
<p class="project-description">
It is a dummy vegan food store website. <br>
This is a fully responsive website made using CSS Flexbox and Grids
</p>
</div>
<div title="techstack used" class="tech-stack-container">
<p class="tech-stack html-logo">HTML</p>
<p class="tech-stack css-logo">CSS</p>
<a title="open repo" href="" class="repo-link">
<i class="fas fa-code repo-logo"></i>
</a>
</div>
</div>
<div class="right-side-card">
<img src="/assets/vegan-store-img.jpg" title="Visit Page" alt="Vegan store" class="project-image"
id="vegan-store-image">
</div>
</div>
</div>
<!-- about section -->
<div id="about" class="about-section section">
<h2>About</h2>
<div class="education-container">
<h3>Education</h3>
</div>
</div>
<!-- Back to top btn -->
<div onclick="moveToTop()" id="bttBtn-wrapper">
<div id="bttBtn">
</div>
</div>
</main>
</body>
</html>
Try this one
const main = document.querySelector('main');
// main.onscroll = logScroll;
main.addEventListener('scroll', logScroll)
function logScroll(e) {
console.log(`Scroll position: ${e.target.scrollTop}`);
if(e.target.scrollTop == 761){
console.log('About Page is Reached');
}
}
Note for target.onscroll
Only one onscroll handler can be assigned to an object at a time. For greater flexibility, you can pass a scroll event to the EventTarget.addEventListener() method instead.
As explained here https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onscroll
As I understand here in my code above, the target.scrollTop will only works when you have selected a valid target in your document object. In this case as I inspect your html markup you have wrapped your whole sections to a main tag.
Now that's it, I tried to get your main tag and add an eventListener to it, and it works to me. Hope this also works to you.
I'm building a card flip matching game. Rather than having the card flip on a mouse click, I want keyboard controls.
I'm having trouble getting the cards to shuffle. The cards will shuffle fine if I use the 'selector' class from the DOM, but I plan to use those as a highlighter/selector icon when then user is toggling through the cards. So I need the cards themselves to shuffle.
Don't mind that most of this code is tailored for clicking with a mouse. I'm still in the middle of modifying it and I need to first be able to shuffle the cards and leave the selector classes.
Here is a snippet of my HTML:
<section class='gameContainer'>
<div class='game'>
<div class='row'>
<div class='selector'>
<div class='card' data-framework='star'>
<img class='frontSide'src='https://drive.google.com/uc?export=view&id=1A_zvQyMfZtwBqiVbYifebM07R15dUVD-'>
<img class='backSide'src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='mushroom'>
<img class='frontSide'src='https://drive.google.com/uc?export=view&id=1VgbaVqfGrAw_RefRbMpaKNW4yuQRA5Lm'>
<img class='backSide'src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='flower'>
<img class='frontSide'src='https://drive.google.com/uc?export=view&id=1Vae7dDSTQmvFlW0hoODvud_Y8_m-VVJk'>
<img class='backSide'src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='coinTen'>
<img class='imageWithNum'src='https://drive.google.com/uc?export=view&id=1aTtc4B_GK_EbUyk6Uhl2HFh7uZrZLahr'>
<img class='backSide'src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='chest'>
<img class='imageWithNum'src='https://drive.google.com/uc?export=view&id=1CYWq7iEShB2YG3bQPUCbihsW9_vzgEL_'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='mushroom'>
<img class='frontSide'src='https://drive.google.com/uc?export=view&id=1VgbaVqfGrAw_RefRbMpaKNW4yuQRA5Lm'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
</div>
</div>
</section>
Here is my CSS:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background-color: #000;
}
#titleContainer {
border: solid 0px red;
width: 50%;
margin: auto;
background-color: #ffe400;
padding: 20px;
}
#title1 {
font-family: '8BITWONDERNominal';
font-weight: normal;
font-style: normal;
color: #1f57b8;
text-align: center;
text-shadow: 1px 2px 0px #ff0000;
}
#title2 {
font-family: '8BITWONDERNominal';
font-weight: normal;
font-style: normal;
text-align: center;
color: #ff0000;
text-shadow: 1px 2px 0px #000;
}
.gameContainer {
border: solid 1px black;
background: repeating-linear-gradient(
-45deg,
#fff,
#fff 10px,
#b30000 10px,
#b30000 20px
);
width: 640px;
height: 500px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
}
.game {
background-color: #000;
width: 90%;
height: 90%;
}
.row {
border: solid 0px red;
width: 100%;
height: 33.333%;
display: flex;
justify-content: space-around;
align-items: center;
padding: 20px;
perspective: 1000px;
}
.selector, .selectorActive {
box-sizing: content-box;
border: solid 8px black;
border-radius: 6px;
position: relative;
width: 15%;
height: 110%;
display: flex;
justify-content: center;
align-items: center;
}
.selectorActive {
border: solid 8px orange;
}
.card {
border: solid 0px aqua;
position: absolute;
display: flex;
width: 90%;
height: 89%;
transform-style: preserve-3d;
transition: transform .5s;
}
.card.flip {
transform: rotateY(180deg);
}
.frontSide, .backSide{
border: solid 0px deeppink;
position: absolute;
width: 100%;
height: 100%;
padding: 24px 9px;
background-color: #ffd1d1;
backface-visibility: hidden;
}
.frontSide {
transform: rotateY(180deg);
}
.imageWithNum {
border: solid 0px deeppink;
position: absolute;
width: 100%;
height: 100%;
padding: 29px 14px 0px;
background-color: #ffd1d1;
backface-visibility: hidden;
transform: rotateY(180deg);
}
.backSide {
background-color: #fff;
}
.cardSelector {
border: solid 8px #ff7b00;
}
Here is my JavaScript. I grab the card classes at the beginning of the script, then at the end there's the shuffle function. Also, don't mind that the For loop starts at 1 rather than 0. That was intended:
const cards = document.querySelectorAll('.card');
let hasFlippedCard = false;
let lockBoard = false;
let firstCard, secondCard;
function flipCard(){
// This will disable any clicks that occur before the non-matched cards reset
if(lockBoard)
return;
// This will prevent a double click on the same card to obtain a match
if(this === firstCard)
return;
this.classList.add('flip');
if(!hasFlippedCard){
// First card is clicked
hasFlippedCard = true;
firstCard = this;
return;
}
// Second card is clicked
secondCard = this;
// Check if cards match
checkForMatch();
}
//This function will check if the two cards chosen match
function checkForMatch(){
let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;
isMatch ? disableCards() : unflipCards();
}
//This function will disable the chosen cards whenever there's a match
function disableCards(){
firstCard.removeEventListener('click', flipCard);
secondCard.removeEventListener('click', flipCard);
resetBoard();
}
//This function will reset the cards if they don't match
function unflipCards(){
lockBoard = true;
setTimeout(() => {
firstCard.classList.remove('flip');
secondCard.classList.remove('flip');
resetBoard();
}, 1500);
}
function resetBoard(){
[hasFlippedCard, lockBoard] = [false, false];
[firstCard, secondCard] = [null, null];
}
(function shuffle(){
for(let x = 1; x < cards.length; x++){
let randomPos = Math.floor(Math.random() * 17);
cards[x].style.order = randomPos;
}
})();
cards.forEach(card => card.addEventListener('click', flipCard));
Also yes, I'm trying to recreate the card flip game from Super Mario Bros. 3. :D
When you specify the order, it applies to the child of the flex container. According to the specification:
The contents of a flex container consists of zero or more flex items:
each child of a flex container becomes a flex item.
Your .card elements do not appear to be children of the flex container. They're descendants of it, but they're children of the .selector elements. If you apply the ordering to the elements with the selector class, I think it should work.
Note that your first card will always be the star, since you're starting your for loop at x = 1. This may be intentional, but I just wanted to point it out.
const cards = document.querySelectorAll('.card');
let hasFlippedCard = false;
let lockBoard = false;
let firstCard, secondCard;
function flipCard() {
// This will disable any clicks that occur before the non-matched cards reset
if (lockBoard)
return;
// This will prevent a double click on the same card to obtain a match
if (this === firstCard)
return;
this.classList.add('flip');
if (!hasFlippedCard) {
// First card is clicked
hasFlippedCard = true;
firstCard = this;
return;
}
// Second card is clicked
secondCard = this;
// Check if cards match
checkForMatch();
}
//This function will check if the two cards chosen match
function checkForMatch() {
let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;
isMatch ? disableCards() : unflipCards();
}
//This function will disable the chosen cards whenever there's a match
function disableCards() {
firstCard.removeEventListener('click', flipCard);
secondCard.removeEventListener('click', flipCard);
resetBoard();
}
//This function will reset the cards if they don't match
function unflipCards() {
lockBoard = true;
setTimeout(() => {
firstCard.classList.remove('flip');
secondCard.classList.remove('flip');
resetBoard();
}, 1500);
}
function resetBoard() {
[hasFlippedCard, lockBoard] = [false, false];
[firstCard, secondCard] = [null, null];
}
(function shuffle() {
let s = document.querySelectorAll(".selector");
for (let x = 1; x < s.length; x++) {
let randomPos = Math.floor(Math.random() * 17);
s[x].style.order = randomPos;
}
})();
cards.forEach(card => card.addEventListener('click', flipCard));
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background-color: #000;
}
#titleContainer {
border: solid 0px red;
width: 50%;
margin: auto;
background-color: #ffe400;
padding: 20px;
}
#title1 {
font-family: '8BITWONDERNominal';
font-weight: normal;
font-style: normal;
color: #1f57b8;
text-align: center;
text-shadow: 1px 2px 0px #ff0000;
}
#title2 {
font-family: '8BITWONDERNominal';
font-weight: normal;
font-style: normal;
text-align: center;
color: #ff0000;
text-shadow: 1px 2px 0px #000;
}
.gameContainer {
border: solid 1px black;
background: repeating-linear-gradient( -45deg, #fff, #fff 10px, #b30000 10px, #b30000 20px);
width: 640px;
height: 500px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
}
.game {
background-color: #000;
width: 90%;
height: 90%;
}
.row {
border: solid 0px red;
width: 100%;
height: 33.333%;
display: flex;
justify-content: space-around;
align-items: center;
padding: 20px;
perspective: 1000px;
}
.selector,
.selectorActive {
box-sizing: content-box;
border: solid 8px black;
border-radius: 6px;
position: relative;
width: 15%;
height: 110%;
display: flex;
justify-content: center;
align-items: center;
}
.selectorActive {
border: solid 8px orange;
}
.card {
border: solid 0px aqua;
position: absolute;
display: flex;
width: 90%;
height: 89%;
transform-style: preserve-3d;
transition: transform .5s;
}
.card.flip {
transform: rotateY(180deg);
}
.frontSide,
.backSide {
border: solid 0px deeppink;
position: absolute;
width: 100%;
height: 100%;
padding: 24px 9px;
background-color: #ffd1d1;
backface-visibility: hidden;
}
.frontSide {
transform: rotateY(180deg);
}
.imageWithNum {
border: solid 0px deeppink;
position: absolute;
width: 100%;
height: 100%;
padding: 29px 14px 0px;
background-color: #ffd1d1;
backface-visibility: hidden;
transform: rotateY(180deg);
}
.backSide {
background-color: #fff;
}
.cardSelector {
border: solid 8px #ff7b00;
}
<section class='gameContainer'>
<div class='game'>
<div class='row'>
<div class='selector'>
<div class='card' data-framework='star'>
<img class='frontSide' src='https://drive.google.com/uc?export=view&id=1A_zvQyMfZtwBqiVbYifebM07R15dUVD-'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='mushroom'>
<img class='frontSide' src='https://drive.google.com/uc?export=view&id=1VgbaVqfGrAw_RefRbMpaKNW4yuQRA5Lm'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='flower'>
<img class='frontSide' src='https://drive.google.com/uc?export=view&id=1Vae7dDSTQmvFlW0hoODvud_Y8_m-VVJk'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='coinTen'>
<img class='imageWithNum' src='https://drive.google.com/uc?export=view&id=1aTtc4B_GK_EbUyk6Uhl2HFh7uZrZLahr'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='chest'>
<img class='imageWithNum' src='https://drive.google.com/uc?export=view&id=1CYWq7iEShB2YG3bQPUCbihsW9_vzgEL_'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
<div class='selector'>
<div class='card' data-framework='mushroom'>
<img class='frontSide' src='https://drive.google.com/uc?export=view&id=1VgbaVqfGrAw_RefRbMpaKNW4yuQRA5Lm'>
<img class='backSide' src='https://drive.google.com/uc?export=view&id=1YUCKsNqGAr81BMW1s8utU3zZFGzvm2uz'>
</div>
</div>
</div>
</div>
</section>
I am trying to create a personal website for me and I am a beginner in html and css. In my work section, i have created multiple buttons which open a small window and give the description of the project. The issue i am facing is all different divs are pointing to last div and the content of the last div is getting copied in all other divs. Thank you so much in advance for helping me out.
Below is the content of my last div:
Below is my image of second div:
Below is the overall code:
$(document).ready(function() {
$(".call_modal").click(function() {
$(".modal").fadeIn();
$(".modal_main").show();
});
});
$(document).ready(function() {
$(".close").click(function() {
$(".modal").fadeOut();
$(".modal_main").fadeOut();
});
});
work body {
margin: 0;
background: #e5eaee;
}
h3 {
font-size: 25px;
font-weight: 700;
text-transform: uppercase;
color: #e1c184;
text-align: center;
padding: 50px 0px 0px;
clear: both;
}
.modal {
width: 100%;
height: 100%;
position: fixed;
top: 0;
display: none;
}
.modal_close {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
position: fixed;
top: 0;
margin-left: -8px;
}
.close {
cursor: pointer;
}
.gl1_content .modal_main {
width: 50%;
height: 500px;
background: #B7BBBE;
z-index: 4;
position: fixed;
top: 16%;
border-radius: 4px;
left: 25%;
overflow: auto;
-webkit-animation-duration: .5s;
-webkit-animation-delay: .0s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
-webkit-backface-visibility: visible!important;
-webkit-animation-name: fadeInRight;
text-align: center;
}
#-webkit-keyframes fadeInRight {
0% {
opacity: 0;
-webkit-transform: translateX(20px)
}
100% {
opacity: 1;
-webkit-transform: translateX(0)
}
}
.gl1_content .content {
padding: 50px 0px 30px;
text-align: justify;
margin-left: 20px;
margin-right: 10px;
}
button {
display: block;
width: 25%;
height: 150px;
padding: 40px;
border-radius: 5px;
background: #3399cc;
border: none;
font-size: 20px;
color: #fff;
margin-top: 40px;
margin-left: 80px;
float: left;
text-align: center;
position: center;
}
.ProjTable {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 50%;
}
.ProjTable td,
#ProjTable th {
border: 1px solid #ddd;
padding: 8px;
}
.ProjTable tr:nth-child(even) {
background-color: #f2f2f2;
}
.ProjTable tr:hover {
background-color: #ddd;
}
.ProjTable th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: white;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://gc.kis.v2.scr.kaspersky-labs.com/B55FB9A2-E45C-3242-96D3-CF26E54EC901/main.js" charset="UTF-8"></script>
<h3 id="work">Work</h3>
<div class="gl_content">
<button class="call_modal" style="cursor:pointer;">SAS Consult and Support</button>
<div class="modal">
<div class="modal_close close"></div>
<div class="modal_main">
<img src="i783wQYjrKQ.png" class="close" style="margin-top:13px;left:96%;position:fixed;">
<div class="content">
<p></p>
</div>
</div>
</div>
</div>
<div class="content">
<button class="call_modal" style="cursor:pointer;">Global Reporting Infrastructure Project (GRIP)</button>
<div class="modal">
<div class="modal_close close"></div>
<div class="modal_main">
<img src="i783wQYjrKQ.png" class="close" style="margin-top:13px;left:96%;position:fixed;">
<div class="content">
<p><strong>Global Reporting Infrastructure Project (GRIP)</strong> is a key global initiative and is aimed at delivering a set of standard reports with standard metrics, definitions and templates across RBWM products Origination, Portfolio Management,
Profitability and RWAs by providing a global platform for Risk data aggregation and reporting. RBWM Risk has historically lacked Group level risk aggregation and reporting capability and relied upon end user computing to produce executive reporting
to drive risk management and decision making. Numerous inconsistencies relating to Key Performance Indicators (KPI) captured, business definitions used, calculations performed and report formats utilized are inherent with this method of reporting.
RBWM Risk management desires a system that will provide more metrics and KPIs to drive better decision making and analysis.</p>
</div>
</div>
</div>
</div>
A generic approach can be:
a) First add a common class(like- 'modal_container') to all the modal containers.
<div class="gl_content modal_container">...</div>
...
<div class="content modal_container">...</div>
...
b) On click event get the immediate modal container element on top of the element that got clicked and show/hide the modal inside it(the modal container).
I have redesigned the code below, please check with it:
<script>
$(document).ready(function(){
$(".call_modal").click(function(){
var modal_container = $(this).closest('.modal_container');
$(".modal", modal_container).fadeIn();
$(".modal_main", modal_container).show();
});
$(".close").click(function(){
var modal_container = $(this).closest('.modal_container');
$(".modal", modal_container).fadeOut();
$(".modal_main", modal_container).fadeOut();
});
});
</script>
You need to change this line of code :
$(".modal").fadeIn();
to be :
$(this).next($(".modal")).fadeIn();
In this case: When you click at any button, the div with class modal after the clicked button only will be work.
$(document).ready(function() {
$(".call_modal").click(function() {
$(this).next($(".modal")).fadeIn();
$(".modal_main").show();
});
});
$(document).ready(function() {
$(".close").click(function() {
$(".modal").fadeOut();
$(".modal_main").fadeOut();
});
});
work body {
margin: 0;
background: #e5eaee;
}
h3 {
font-size: 25px;
font-weight: 700;
text-transform: uppercase;
color: #e1c184;
text-align: center;
padding: 50px 0px 0px;
clear: both;
}
.modal {
width: 100%;
height: 100%;
position: fixed;
top: 0;
display: none;
}
.modal_close {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
position: fixed;
top: 0;
margin-left: -8px;
}
.close {
cursor: pointer;
}
.gl1_content .modal_main {
width: 50%;
height: 500px;
background: #B7BBBE;
z-index: 4;
position: fixed;
top: 16%;
border-radius: 4px;
left: 25%;
overflow: auto;
-webkit-animation-duration: .5s;
-webkit-animation-delay: .0s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
-webkit-backface-visibility: visible!important;
-webkit-animation-name: fadeInRight;
text-align: center;
}
#-webkit-keyframes fadeInRight {
0% {
opacity: 0;
-webkit-transform: translateX(20px)
}
100% {
opacity: 1;
-webkit-transform: translateX(0)
}
}
.gl1_content .content {
padding: 50px 0px 30px;
text-align: justify;
margin-left: 20px;
margin-right: 10px;
}
button {
display: block;
width: 25%;
height: 150px;
padding: 40px;
border-radius: 5px;
background: #3399cc;
border: none;
font-size: 20px;
color: #fff;
margin-top: 40px;
margin-left: 80px;
float: left;
text-align: center;
position: center;
}
.ProjTable {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 50%;
}
.ProjTable td,
#ProjTable th {
border: 1px solid #ddd;
padding: 8px;
}
.ProjTable tr:nth-child(even) {
background-color: #f2f2f2;
}
.ProjTable tr:hover {
background-color: #ddd;
}
.ProjTable th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: white;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 id="work">Work</h3>
<div class="gl_content">
<button class="call_modal" style="cursor:pointer;">SAS Consult and Support</button>
<div class="modal">
<div class="modal_close close"></div>
<div class="modal_main">
<img src="https://images.pexels.com/photos/34950/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350" class="close" style="margin-top:13px;left:96%;position:fixed;">
<div class="content">
<p></p>
</div>
</div>
</div>
</div>
<div class="content">
<button class="call_modal" style="cursor:pointer;">Global Reporting Infrastructure Project (GRIP)</button>
<div class="modal">
<div class="modal_close close"></div>
<div class="modal_main">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTQxuLL7OoxpB8Eju7xawRbmtMl855M2e09m1-_30NDM8i_m2vr" class="close" style="margin-top:13px;left:96%;position:fixed;">
<div class="content">
<p><strong>Global Reporting Infrastructure Project (GRIP)</strong> is a key global initiative and is aimed at delivering a set of standard reports with standard metrics, definitions and templates across RBWM products Origination, Portfolio Management,
Profitability and RWAs by providing a global platform for Risk data aggregation and reporting. RBWM Risk has historically lacked Group level risk aggregation and reporting capability and relied upon end user computing to produce executive reporting
to drive risk management and decision making. Numerous inconsistencies relating to Key Performance Indicators (KPI) captured, business definitions used, calculations performed and report formats utilized are inherent with this method of reporting.
RBWM Risk management desires a system that will provide more metrics and KPIs to drive better decision making and analysis.</p>
</div>
</div>
</div>
</div>