This is a reference image of what I'm trying to do
I have tried to make a carousel with cards, but I have not been able to make the indicator of the buttons and the card advance when pressing the buttons, as shown in the image. Could you give me a hand to know how to make the indicator and the card advance as it is clicked?
let targeta = document.querySelectorAll('.card');
let puntos = document.querySelectorAll('.secciones .punto');
for (i = 0; i < targeta.length; i++) {
puntos[i].addEventListener('click', function(evento) {
for (i = 0; i < puntos.length; i++) {
puntos[i].classList.remove('activo');
}
clase_activo(evento);
});
targeta[i].addEventListener('click', function(evento) {
for (i = 0; i < puntos.length; i++) {
targeta[i].classList.remove('activo');
}
clase_activo(evento);
});
}
function clase_activo(evento) {
if (evento.target.classList.contains('activo')) {
evento.target.classList.remove('activo');
} else {
evento.target.classList.add('activo');
}
}
.product-list {
background: #dfe6e9;
padding: 3em;
}
.product-list .card {
background: white;
border-radius: 10px;
padding: 1em;
box-shadow: 0px 10px 5px #b2bec3;
text-align: center;
font-family: 'SpaceGrotesk-medium';
}
.card {
height: 300px;
}
.product-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 20px;
grid-row-gap: 40px;
}
.secciones {
display: flex;
align-items: center;
/* background: #fb6969;*/
justify-content: center;
}
.punto {
background: #b4f028;
/* #fb9769; */
height: 10px;
width: 30px;
border-radius: 5px;
padding: 0 5px;
margin: 0 2px;
}
.punto.activo {
background: #f07e28;
/* #fb9769; */
}
.card.activo {
background: #f07e28;
}
<section class="product-list">
<h1>productos</h1>
<div class="product-container">
<div class="card 1 activo">
</div>
<div class="card 2 ">
</div>
<div class="card 3 ">
</div>
<div class="card 4 ">
</div>
</div>
<div class="secciones">
<div class="punto activo"></div>
<div class="punto "></div>
<div class="punto "></div>
<div class="punto "></div>
</div>
</section>
I used a loop to attach click events to both the cards and the dots. When either a card or a dot is clicked, the active class is removed from all cards and dots, and then added to the clicked item and its corresponding item.
// select all cards and dots
let cards = document.querySelectorAll('.card');
let dots = document.querySelectorAll('.secciones .punto');
// loop through each card and dot
for (let i = 0; i < cards.length; i++) {
// attach click event to each card
cards[i].addEventListener('click', function() {
for (let j = 0; j < cards.length; j++) {
// remove the active class from all cards
cards[j].classList.remove('activo');
dots[j].classList.remove('activo');
}
// add the active class to the clicked card
this.classList.add('activo');
dots[i].classList.add('activo');
});
// attach click event to each dot
dots[i].addEventListener('click', function() {
for (let j = 0; j < cards.length; j++) {
// remove the active class from all cards
cards[j].classList.remove('activo');
dots[j].classList.remove('activo');
}
// add the active class to the corresponding card
cards[i].classList.add('activo');
this.classList.add('activo');
});
}
Related
Hope you all have a nice day and Happy Weekend!
I want to ask about adding prev and next button in my Tabs. I already add it, with some JavaScript that referenced to this https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow.
I know it's kind of weird to reference tab with the carousel but, I think that the principle is the same. But in my code, i don't know how to code it. I'm so sorry because I'm very noob in JavaScript. So, here's my attempt :
//Add & remove class tab, contents, & menu on click
window.addEventListener('DOMContentLoaded', ()=> {
let tabs = document.querySelectorAll('.tab');
let content = document.querySelectorAll('.content');
let prev = document.querySelector('.previous');
let next = document.querySelector('.next');
let firstTab = function(tabs) {tabs.classList.add('tab-active')};
let firstContent = function(content) {content.classList.add('content-active')};
firstTab(tabs[0]);
firstContent(content[0]);
for (let i = 0; i < tabs.length; i++) {
tabs[i].addEventListener('click', () => tabClick(i));
}
prev.addEventListener('click', (i) => tabClick(i - 1));
next.addEventListener('click', (i) => tabClick(i + 1));
function tabClick(currentTab) {
removeActive();
//Add Active Class
tabs[currentTab].classList.add('tab-active');
content[currentTab].classList.add('content-active');
}
function removeActive() {
for (let i = 0; i < tabs.length; i++) {
//Remove Active Class
content[i].classList.remove('content-active');
content[i].classList.add('content-show');
setTimeout(function() {
content[i].classList.remove('content-show');
},1500);
tabs[i].classList.remove('tab-active');
}
}
})
/* WHOLE CONTAINER */
.container {
width: 96vw;
height: 96vh;
}
/* TABS */
.tabs {
display: flex;
height: 50px;
overflow: hidden;
align-items: center;
justify-content: center;
width: 100%;
}
.tab {
font-size: 14px;
padding: 5px 10px;
cursor: pointer;
letter-spacing: 2px;
}
#red.tab-active {background-color: rgb(245, 66, 66);}
#blue.tab-active {background-color: rgb(66, 135, 245);}
#yellow.tab-active {background-color: rgb(245, 215, 66);}
#green.tab-active {background-color: rgb(56, 235, 98);}
#cyan.tab-active {background-color: rgb(79, 247, 219);}
/* TAB CONTENTS */
.contents {
width: 100%;
margin-top: 5px;
height: 80%;
}
.content {
width: 96%;
height: 80%;
display: none;
padding: 0;
margin: 0;
border: none;
position: absolute;
}
.content-show {
display: flex;
animation-name: fade-out;
animation-duration: 2.5s;
}
#keyframes fade-out {
0% {
opacity: 1;
display: flex;
}
99% {
opacity: 0;
display: flex;
}
100% {
opacity: 0;
display: none;
}
}
.content-active {
display: flex;
border: none;
justify-content: center;
animation-name: fade-in;
animation-duration: 2.5s;
}
#keyframes fade-in {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0.01;
}
100%{
display: block;
opacity: 1;
}
}
#red.content-active {background-color: rgb(245, 66, 66);}
#blue.content-active {background-color: rgb(66, 135, 245);}
#yellow.content-active {background-color: rgb(245, 215, 66);}
#green.content-active {background-color: rgb(56, 235, 98);}
#cyan.content-active {background-color: rgb(79, 247, 219);}
/* BUTTON PREVIOUS NEXT */
.button {
position: absolute;
top: 49%;
z-index: 4;
}
.previous, .next {
margin: 5px 10px;
letter-spacing: 2px;
background-color: white;
font-size: 14px;
text-align: center;
padding: 5px;
cursor: pointer;
}
<div class="container">
<div class="tabs">
<div id="red" class="tab">RED</div>
<div id="blue" class="tab">BLUE</div>
<div id="yellow" class="tab">YELLOW</div>
<div id="green" class="tab">GREEN</div>
<div id="cyan" class="tab">CYAN</div>
</div>
<div class="contents">
<div id="red" class="content"></div>
<div id="blue" class="content"></div>
<div id="yellow" class="content"></div>
<div id="green" class="content"></div>
<div id="cyan" class="content"></div>
</div>
<div class="button">
<div class="previous">PREV</div>
<div class="next">NEXT</div>
</div>
</div>
Please help me to solve this code guys. Thanks a lot.
The only problem that you are facing is when you click on the prev or next button you have passed the argument i in tabClick function but i is not the index rather it is the property of click event.
Here's what you have done 👇
prev.addEventListener('click', (i) => tabClick(i - 1));
next.addEventListener('click', (i) => tabClick(i + 1));
Here i represents the property of click and the element you have clicked on so it does not give the index.
What you can rather do is:
Create a global variable called activeTab and set the default to 0.
Inside tabClick fucntion set activeTab to currentTab as activeTab = currentTab
Now, inside prev function write tabClick(actie - 1)
Follow the same for next function.
Here's my code 👇
//Add & remove class tab, contents, & menu on click
window.addEventListener('DOMContentLoaded', ()=> {
let tabs = document.querySelectorAll('.tab');
let content = document.querySelectorAll('.content');
let prev = document.querySelector('.previous');
let next = document.querySelector('.next');
let firstTab = function(tabs) {tabs.classList.add('tab-active')};
let firstContent = function(content) {content.classList.add('content-active')};
let actieTab = 0;
firstTab(tabs[0]);
firstContent(content[0]);
for (let i = 0; i < tabs.length; i++) {
tabs[i].addEventListener('click', () => tabClick(i));
}
prev.addEventListener('click', () => tabClick(activeTab - 1));
next.addEventListener('click', () => tabClick(activeTab + 1));
function tabClick(currentTab) {
removeActive();
//Add Active Class
tabs[currentTab].classList.add('tab-active');
content[currentTab].classList.add('content-active');
activeTab = currentTab
}
function removeActive() {
for (let i = 0; i < tabs.length; i++) {
//Remove Active Class
content[i].classList.remove('content-active');
content[i].classList.add('content-show');
setTimeout(function() {
content[i].classList.remove('content-show');
},1500);
tabs[i].classList.remove('tab-active');
}
}
})
For the issue that no class is selected after the end of the array, you can do this 👇
Add a codition to check if the activeTab is at the end of the array.
If it is, we set activeTab back to 0 and call the function tabClick and pass the activeTab in it
If not, in else we'll do the same thing which we were doing before
Follow the same for prev button
Code example
prev.addEventListener("click", (i) => {
if (activeTab === 0) {
activeTab = tabs.length - 1;
tabClick(activeTab);
} else {
tabClick(activeTab - 1);
}
});
next.addEventListener("click", (i) => {
if (activeTab >= tabs.length - 1) {
activeTab = 0;
tabClick(activeTab);
} else {
tabClick(activeTab + 1);
}
});
So basically this is Day 3 (other days, I pretty much did nothing to complete the game) of making a game from HTML5. So I'm making a moves system right now, and I guess I'm doing well? (mainly because I'm not sure if I provided the user with too many moves...) But the thing about it is that, I'm kind of having ANOTHER styling issue.
As you can see in the image: I've CLEARLY set dimensions up for the headerDisplay class/id, but NO, it goes out of the div's dimensions and even goes on the grid. I'm also aiming for the time and moves text to be stuck right on top of the grid, similarly to how the word bank is stuck to the bottom of the grid.
I was also aiming for a button that says refresh right under the word bank, however no matter what I tried, the button would just be right the score text, which looks like this:
When I am aiming for this:
Code:
<div class="content" id="content">
<div class="headerDisplay" id="headerDisplay">
</div>
<div class="gameArea" id="gameArea">
</div>
<div class="wordBank" id="wordBank">
</div>
<div class="bottomMenu" id="bottomMenu">
</div>
</div>
::before,
::after {
box-sizing: border-box;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.content {
display: grid;
grid-template-rows: repeat(3, max-content);
margin-block: 1em;
margin-inline: auto;
width: 512px;
}
.bottomMenu {
font-size: 24px;
text-align: right;
}
.wordBank {
border: 2.5px solid #000;
border-radius: 5px;
display: flex;
font-size: 1.6em;
min-height: 3em;
justify-content: space-between;
padding: 0.25em;
}
.wordBank span:nth-child(even) {
align-self: end;
}
.gameArea {
font-size: 0;
justify-self: center;
max-width: 100%;
}
.cell {
border: 1px solid black;
width: 50px;
font-size: 1rem;
height: 50px;
display: inline-block;
}
.headerDisplay {
width: 100%;
height: 76.8px;
text-align: right;
font-size: 1.6em;
}
let score = 0;
const headerDisplay = document.getElementById("headerDisplay")
const bottomMenu = document.getElementById("bottomMenu");
const wordBank = document.getElementById("wordBank")
const gameArea = document.getElementById("gameArea")
const rows = document.getElementsByClassName("gridRow");
const cells = document.getElementsByClassName("cell");
const words = [ // snippet
"ability",
"able",
"about",
"above",
"abroad",
"absence",
"absent",
"absolute",
"accept",
"accident",
"accord",
"account",
"accuse",
"accustom",
"ache",
"across",
"act"
]
let selectedWords = [];
bottomMenu.innerHTML = "<p>Score: " + score;
bottomMenu.innerHTML += "<button>Refresh"
while (selectedWords.length < 5) {
const selectedWord = words[Math.floor(Math.random() * words.length)];
if (selectedWord.length <= 9) {
wordBank.innerHTML += "<span>" + selectedWord + "</span>"
selectedWords.push(selectedWord);
}
}
let longestWord = selectedWords.reduce((a, b) => a.length < b.length ? b : a, "")
let charCount = longestWord.length
var moves = charCount * 5
headerDisplay.innerHTML += "<p>Time: "
headerDisplay.innerHTML += "<p>Moves: " + moves
function makeRows(rowNum) {
for (let r = 0; r < rowNum; r++) {
let row = document.createElement("div");
gameArea.appendChild(row).className = "gridRow";
}
}
function makeColumns(cellNum) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < cellNum; j++) {
let newCell = document.createElement("div");
rows[j].appendChild(newCell).className = "cell";
}
}
}
function defaultGrid() {
makeRows(charCount);
makeColumns(charCount);
}
defaultGrid();
To fix header you need to set its height to fit content, so it will be over your grid even if you change it later:
.headerDisplay {
width: 100%;
height: content-fit; /* previous: 76.8px */
text-align: right;
font-size: 1.6em;
}
And to fix bottom menu you need to add flexbox:
.bottomMenu {
font-size: 24px;
text-align: right;
display: flex; /* new */
flex-direction: row-reverse; /* new */
justify-content: space-between; /* new */
align-items: center; /* new */
}
For the button, you could try this:
button {
position: relative;
right: 400px;
bottom: 50px;
transform: scale(2,2)
}
I trying to create 121 divs through the DOM, and append to the .container div
const container= document.querySelector('.container');
const divNumber= 121;
for (let i= 0; i<= 121; i++){
const divs= document.createElement('div');
divs.classList.add('items');
container.appendChild(divs);
}
.container {
display: grid;
grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto;
}
.items {
border: 1px solid black;
margin: 0px;
}
<div class='container'></div>
Nothing seems to happen on the webpage. How can I make 11 by 11 which equals 121 divs through the DOM and append them to the parent div, .container in this case?
All grids are overlapping. Add grid-gap property
const container = document.querySelector('.container');
const divNumber = 121;
for (let i = 0; i < 121; i++) {
const divs = document.createElement('div');
divs.classList.add('items');
divs.innerHTML = i + 1
container.appendChild(divs);
}
.container {
display: grid;
grid-template-columns: repeat(11,1fr);
grid-gap: 20px;
}
.items {
border: 1px solid black;
margin: 0px;
padding: 5px;
color: green;
}
<div class='container'></div>
I have this code:
<div class="places-item">
<div class="places-item-img"></div>
<div class="places-item-header">
<h2>Machu Picchu, Peru</h2>
<div class="places-item-header-add"><svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path d='M352,48H160a48,48,0,0,0-48,48V464L256,336,400,464V96A48,48,0,0,0,352,48Z' style='fill:transparent;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/></svg></div>
</div>
</div>
<div class="places-item">
<div class="places-item-img"></div>
<div class="places-item-header">
<h2>CiucaÈ™ Peak, Romania</h2>
<div class="places-item-header-add"><svg xmlns='http://www.w3.org/2000/svg' width='512' height='512' viewBox='0 0 512 512'><path d='M352,48H160a48,48,0,0,0-48,48V464L256,336,400,464V96A48,48,0,0,0,352,48Z' style='fill:transparent;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/></svg></div>
</div>
</div>
.places-item {
width: 100%;
}
.places-item-img {
width: 100%;
height: 350px;
background-color: cyan;
}
.places-item-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1em 0;
}
.places-item-header h2 {
font-size: 24px;
max-width: calc(100% - 38px);
}
.places-item-header-add {
width: 28px;
height: 28px;
cursor: pointer;
}
.places-item-header-add svg {
width: 100%;
height: 100%;
}
.places-item-header-add.added svg path {
fill: #000 !important;
}
var addBtn = document.querySelectorAll('.places-item-header-add');
for(i=0;i<addBtn.length;++i)addBtn[i].addEventListener('click',function(){
this.classList.toggle('added');
});
When you click on the icon, it becomes black. What can I do to make the icon that was clicked (there may be several of them) black after refreshing the page? I was planning to do this at localStorage.
Be specific to your elements, add ids so that we can specify which item was active.
example.
add id to your item header.
<div id='peru' class="places-item-header-add">
and when the window is loaded check the value in the localstorage and update the item class.
var addBtn = document.querySelectorAll('.places-item-header-add');
var items = JSON.parse(localStorage.getItem('selected_items')) || {};
for (i = 0; i < addBtn.length; ++i) {
if (items[addBtn[i].id]) {
addBtn[i].classList.add('added');
}
addBtn[i].addEventListener('click', function() {
this.classList.toggle('added');
if (this.classList.contains('added')) {
items[this.id] = true;
} else {
items[this.id] = false;
}
localStorage.setItem('selected_items', JSON.stringify(items));
})
}
Check this fiddle
https://jsfiddle.net/uwqevc65/
I have a div class called box and this div forms a square.I want to repeat this div in order to form a 3 X 3 grid.How can i do this using for loop in javascript/jquery?
.box {
background: #9E9E9E;
border:black 1px solid;
width: 180px;
height:180px;
margin:0px auto;
margin-top:0px;
cursor:pointer;
display: inline-block;
float: left;
}
Here is a simple (should be easy to understand) solution, change it as you wish according to your own needs:
NOTE: In future to not get your Question down-voted follow these links...
CSS:
.box {
background: #9E9E9E;
border: black 1px solid;
width: 180px;
height: 180px;
margin: 0 auto;
margin-top: 0;
cursor: pointer;
display: inline-block;
float: left;
}
.row {
display: block;
float:left;
width:100%;
}
JS:
function makeBlocks() {
for (var i = 0; i < 3; i++) {
var row = document.createElement('div');
row.className = "row";
for (var j = 0; j < 3; j++) {
var box = document.createElement('div');
box.className = "box";
row.appendChild(box);
}
document.getElementById('boxParent').appendChild(row);
}
}
HTML:
<div>
<div id="boxParent"></div>
</div>
<div>
<button onclick="makeBlocks();">MAKE BLOCKS</button>
</div>
EDIT:
Here's a JSFiddle link
I give you a starting point:
<div class="parent">
<div class="toCopy">div that i have to clone</div>
</div>
$( ".toCopy" ).clone().appendTo( ".parent" );
result:
<div class="parent">
<div class="toCopy">div that i have to clone</div>
<div class="toCopy">div that i have to clone</div>
</div>
if you don't have class names, you can traverse the dom with jquery traversing: https://api.jquery.com/category/traversing/
Anyway I suggest you to check the manipulation section of the api: https://api.jquery.com/category/manipulation/
Do you want something like this:
http://jsfiddle.net/sqz75b9g/8/
HTML
<div class="rows">
<div class="row0"></div>
<div class="row1"></div>
<div class="row2"></div>
</div>
JQuery Code:
$(function() {
for(var row=0;row<3;row++)
{
for(var col=0;col<3;col++)
{
$(".row"+row).append("<div class='box'></div>");
}
}
})