.click function is executed multiple times on every click - javascript

I am using an expandable card grid from CodePen (https://cdpn.io/nailaahmad/fullpage/LGRxWJ).
I added a button at the end of each card to close the current card and open the next one. It works well when you open the first card and click through all the card using that button at the end of each card. The cards can also be opened and closed by clicking on the card__inner element. When I mix the card__inner and the end of card navigation method, the function closeThisAndOpenNext is executed multiple times on every click of the and not the adjacent card is opened, but one further away from the open card.
Does anyone know why and how to fix it so that only the card right next to the open card is opened with the "next"-button at the end of the card?
var $cell = $('.card');
$('.js-next').hide();
//open and close card when clicked on card
$cell.find('.js-expander').click(function() {
function getIndexOfList(list, element) {
var $index = 0;
for (let index = 0; index < $cell.length; index++) {
const item = $cell[index];
if (item == element[0]) {
$index = index;
break;
}
}
return $index;
}
function closeThisAndOpenNext() {
var $currentCard = $('.is-expanded')[0];
$($currentCard).removeClass('is-expanded').addClass('is-collapsed');
$($currentCard).find('.js-next:first').hide();
//var $index = getIndexOfList($cell, $currentCard);
$index = $($currentCard).data('index');
if ($index < 9) {
$nextCard = $cell[$index + 1];
} else {
return;
}
$($nextCard).removeClass('is-collapsed').addClass('is-expanded');
$($nextCard).find('.js-next:first').show();
$nextButton = $($nextCard).find('.js-next:first');
if ($nextButton.length > 0 && $nextButton[0].onclick == null) {
$($nextButton).click(closeThisAndOpenNext);
}
}
var $thisCell = null;
if ($(this).find('.is-expanded').length == 0) {
$thisCell = $(this).closest('.card');
} else {
$thisCell = $(this).find('.is-expanded:first');
}
if ($thisCell.hasClass('is-collapsed')) {
$cell.not($thisCell).removeClass('is-expanded').addClass('is-collapsed').addClass('is-inactive');
$thisCell.removeClass('is-collapsed').addClass('is-expanded');
$($thisCell).find('.js-next:first').show();
if ($cell.not($thisCell).hasClass('is-inactive')) {
//do nothing
} else {
$cell.not($thisCell).addClass('is-inactive');
}
$nextButton = $thisCell.find('.js-next:first');
$($nextButton).click(closeThisAndOpenNext);
} else {
$thisCell.removeClass('is-expanded').addClass('is-collapsed');
$cell.not($thisCell).removeClass('is-inactive');
$($thisCell).find('.js-next:first').hide();
}
});
//close card when click on cross
$cell.find('.js-collapser').click(function() {
var $thisCell = $(this).closest('.card');
$thisCell.removeClass('is-expanded').addClass('is-collapsed');
$cell.not($thisCell).removeClass('is-inactive');
$($thisCell).find('.js-next:first').hide();
});
#charset "UTF-8";
* {
box-sizing: border-box;
}
body {
background: #eceef1;
font-family: "Slabo 27px", serif;
color: #333a45;
}
.wrapper {
margin: 5em auto;
max-width: 1000px;
background-color: #fff;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.06);
}
.header {
padding: 30px 30px 0;
text-align: center;
}
.header__title {
margin: 0;
text-transform: uppercase;
font-size: 2.5em;
font-weight: 500;
line-height: 1.1;
}
.header__subtitle {
margin: 0;
font-size: 1.5em;
color: #949fb0;
font-family: "Yesteryear", cursive;
font-weight: 500;
line-height: 1.1;
}
.cards {
padding: 15px;
display: flex;
flex-flow: row wrap;
}
.card {
margin: 15px;
width: calc((100% / 3) - 30px);
transition: all 0.2s ease-in-out;
}
#media screen and (max-width: 991px) {
.card {
width: calc((100% / 2) - 30px);
}
}
#media screen and (max-width: 767px) {
.card {
width: 100%;
}
}
.card:hover .card__inner {
background-color: #1abc9c;
transform: scale(1.05);
}
.card__inner {
width: 100%;
padding: 30px;
position: relative;
cursor: pointer;
background-color: #949fb0;
color: #eceef1;
font-size: 1.5em;
text-transform: uppercase;
text-align: center;
transition: all 0.2s ease-in-out;
}
.card__inner:after {
transition: all 0.3s ease-in-out;
}
.card__inner .fa {
width: 100%;
margin-top: 0.25em;
}
.card__expander {
transition: all 0.2s ease-in-out;
background-color: #333a45;
width: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
color: #eceef1;
font-size: 1.5em;
}
.card__expander .fa {
font-size: 0.75em;
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
}
.card__expander .fa:hover {
opacity: 0.9;
}
.card.is-collapsed .card__inner:after {
content: "";
opacity: 0;
}
.card.is-collapsed .card__expander {
max-height: 0;
min-height: 0;
overflow: hidden;
margin-top: 0;
opacity: 0;
}
.card.is-expanded .card__inner {
background-color: #1abc9c;
}
.card.is-expanded .card__inner:after {
content: "";
opacity: 1;
display: block;
height: 0;
width: 0;
position: absolute;
bottom: -30px;
left: calc(50% - 15px);
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid #333a45;
}
.card.is-expanded .card__inner .fa:before {
content: "";
}
.card.is-expanded .card__expander {
max-height: 1000px;
min-height: 200px;
overflow: visible;
margin-top: 30px;
opacity: 1;
}
.card.is-expanded:hover .card__inner {
transform: scale(1);
}
.card.is-inactive .card__inner {
pointer-events: none;
opacity: 0.5;
}
.card.is-inactive:hover .card__inner {
background-color: #949fb0;
transform: scale(1);
}
#media screen and (min-width: 992px) {
.card:nth-of-type(3n+2) .card__expander {
margin-left: calc(-100% - 30px);
}
.card:nth-of-type(3n+3) .card__expander {
margin-left: calc(-200% - 60px);
}
.card:nth-of-type(3n+4) {
clear: left;
}
.card__expander {
width: calc(300% + 60px);
}
}
#media screen and (min-width: 768px) and (max-width: 991px) {
.card:nth-of-type(2n+2) .card__expander {
margin-left: calc(-100% - 30px);
}
.card:nth-of-type(2n+3) {
clear: left;
}
.card__expander {
width: calc(200% + 30px);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="apple-touch-icon" type="image/png" href="https://cpwebassets.codepen.io/assets/favicon/apple-touch-icon-5ae1a0698dcc2402e9712f7d01ed509a57814f994c660df9f7a952f3060705ee.png" />
<meta name="apple-mobile-web-app-title" content="CodePen">
<link rel="shortcut icon" type="image/x-icon" href="https://cpwebassets.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico" />
<link rel="mask-icon" type="" href="https://cpwebassets.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111" />
<title>CodePen - Expanding Card Grid With Flexbox</title>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Slabo+27px|Yesteryear'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'>
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
</head>
<body translate="no">
<div class="wrapper">
<div class="header">
<h1 class="header__title">Expanding Card Grid</h1>
<h2 class="header__subtitle">with Flexbox</h2>
</div>
<div class="cards">
<div class=" card [ is-collapsed ] " data-index="0">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="1">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="2">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="3">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="4">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="5">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="6">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="7">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="8">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
<div class="text-center js-next"><i class="fa fa-angle-double-down"></i></div>
</div>
<div class=" card [ is-collapsed ] " data-index="9">
<div class="card__inner [ js-expander ]">
<span>Card</span>
<i class="fa fa-folder-o"></i>
</div>
<div class="card__expander">
<i class="fa fa-close [ js-collapser ]"></i> Expander
</div>
</div>
</div>
</div>
<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-1b93190375e9ccc259df3a57c1abc0e64599724ae30d7ea4c6877eb615f89387.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
</body>
</html>

$($nextButton).click(closeThisAndOpenNext) assigns an event handler. Every time this line runs, another event handler is assigned. Or at least this is my memory of how this is supposed to work. I haven't researched it for this answer.
But the idea is the same. Any time you see the same behavior on click happen many times instead of the one time you expect, you probably have multiple handlers of the same func assigned.
I suggest not having multiple functions inside of functions here, and make sure that things that you only want to happen once, at least check to see if it's already happened (been assigned) before doing it again.

Related

how to make my side menu responsive to 990px?

I made this side menu, which has the icons fixed on the screen on the side, when clicking on the bars opens the full menu. I just can't think of a way to make it responsive, I'd like to make only the menu bars appear in the header when it's 990px, but I can't think of a way to show the icons and the full menu when I click, how can I do that that?
const openBtn = $('.open-btn');
const closeBtn = $('.close-btn');
const offcanvasMenu = $('.offcanvas-menu')
openBtn.on('click', function (e) {
e.preventDefault();
if (offcanvasMenu.hasClass('active')) {
offcanvasMenu.removeClass('active');
} else {
offcanvasMenu.addClass('active');
}
});
const mouseoverEvent = new Event('mouseenter');
$(".offcanvas-menu a, .icons a").hover(function (obj) {
const classname = obj.target.classList[0];
$("."+classname).each((function (i,obj) {
obj.classList.add("hover")
}))
},
function (obj) {
const classname = obj.target.classList[0];
$("."+classname).each((function (i,obj) {
obj.classList.remove("hover")
}))
});
.header-area {
background: #111;
display: flex;
height: 40px;
align-items: center;
justify-content: space-between;
}
a{
text-decoration: none !important;
color: #fff !important;
}
.logo a {
font-size: 30px;
font-family: 'Open Sans', sans-serif;
color: #fff;
font-weight: 700;
line-height: 1.5;
text-decoration: none;
display: inline-block;
margin-left: 50px;
}
.icons {
position: absolute;
height: 100vh;
width: 60px;
background-color: #111;
top: 0;
left: 0;
z-index: 9;
}
.icons a{
height: 40px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.offcanvas-menu a{
height: 40px;
width: 100%;
display: flex;
align-items: center;
justify-content: start;
}
.offcanvas-menu a{
padding: 0 1.5rem;
}
.offcanvas-menu {
padding-top: 56px;
position: fixed;
top: 0;
left: 0;
background: #111;
width: auto;
height: 100vh;
transform: translateX(-100%);
transition: all .4s ease;
z-index: 0;
}
.offcanvas-menu.active {
transform: translateX(60px);
}
.close-btn {
position: absolute;
top: 10px;
right: 30px;
font-size: 20px;
color: #fff;
}
a.hover{
color: #000 !important;
background-color: #fff;
}
<!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>Off Canvas Menu</title>
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
</head>
<body>
<!-- Header Area Start -->
<header class="header-area">
<nav class="icons d-flex flex-column align-items-center gap-3 text-light">
<a class="open-btn" href="#">
<i class="fa-solid fa-bars"></i>
</a>
<a class="home">
<i class="fa-solid fa-house"></i>
</a>
<a class="plants">
<i class="fa-solid fa-solar-panel"></i>
</a>
<a class="calendar">
<i class="fa-solid fa-calendar-days"></i>
</a>
<a class="form">
<i class="fa-solid fa-table-list"></i>
</a>
<a class="reports">
<i class="fa-solid fa-file-invoice-dollar"></i>
</a>
<a class="credit">
<i class="fa-solid fa-circle-dollar-to-slot"></i>
</a>
<a class="plantUcs">
<i class="fa-solid fa-building-user"></i>
</a>
<a class="invoice">
<i class="fa-solid fa-barcode"></i>
</a>
<a class="ucs">
<i class="fa-solid fa-city"></i>
</a>
<a class="client">
<i class="fa-solid fa-users"></i>
</a>
<a class="analysis">
<i class="fa-solid fa-magnifying-glass-chart"></i>
</a>
<a class="signature">
<i class="fa-solid fa-file-signature"></i>
</a>
<a class="monitoring">
<i class="fa-solid fa-file-invoice"></i>
</a>
<a class="contact">
<i class="fa-solid fa-headset"></i>
</a>
<a class="config">
<i class="fa-solid fa-gear"></i>
</a>
<a class="user">
<i class="fa-solid fa-user"></i>
</a>
</nav>
<nav class="offcanvas-menu main-menu d-flex flex-column align-items-center gap-3 text-light">
Home
Usinas
Calendário
Formulários
Relatórios
Sistema de crédito
UCS da usina
Faturas
UCS
Clientes
Análises
Gerenciamento de assinatura
Portais de monitoramento
Contato
Configurações
<a href="#" class="user">
<i class="fa-solid fa-arrow-right fa-2xs me-3"></i>
Sair
</a>
</nav>
</header>
<!-- Header Area End -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Expecting that this class opens the menu.
.offcanvas-menu.active {
transform: translateX(60px);
}
Can add a media prop to your css like so
#media (max-width:990px) {
.offcanvas-menu {
transform: translateX(60px) !important;
}
}
which will open the menu when window is larger than 990px.
Try omitting the !important keyword if it works without it.
Having multiple same values in css can be annoying at times. Can use :root directive to help with that.
As an exmaple
:root {
--menu-translate-x: 60px;
}
.offcanvas-menu.active {
transform: translateX(var(--menu-translate-x));
}

Unable to toggle between division

I am creating a portfolio by watching this tutorial - https://www.youtube.com/watch?v=27JtRAI3QO8&list=WL&index=12 (I am stuck at 1:12:13)
I have created a qualification section. there are two division that is education and work.
By default it shows education tab. when I click on the work tab it shows content in the work tab. But when I click back on the education tab it doesn't show the content of the education tab.
actually i am beginner to js. i am unable to get the error in the js file.
my Html code is
<section class="qualification section">
<h2 class="section_title">Qualification</h2>
<span class="section_subtitle">My personal journey</span>
<div class="q_container container">
<div class="q_tabs">
<div class="q_btn btn-flex q_active " data-target ='#education'>
<i class="uil uil-graduation-cap q_icon"></i>Education
</div>
<div class="q_btn btn-flex " data-target ='#work'>
<i class="uil uil-briefcase-alt q_icon"></i>Work
</div>
</div>
<div class="q_section">
<!--==================== QUALIFICATION c1====================-->
<div class="q_content q_active " data-content id="Education">
<!--==================== QUALIFICATION --1====================-->
<div class="q_data">
<div>
<h3 class="q_title">Electronics and communication Engineer</h3>
<span class="q_subtitle">M. S Ramaiah University of Applied Sciences</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>2018-2022
</div>
</div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
</div>
<!--==================== QUALIFICATION --2====================-->
<div class="q_data">
<div></div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
<div>
<h3 class="q_title">PUC</h3>
<span class="q_subtitle">Gurukula independent PU college of science</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>2016-2018
</div>
</div>
</div>
<!--==================== QUALIFICATION --3====================-->
<div class="q_data">
<div>
<h3 class="q_title">SSLC</h3>
<span class="q_subtitle">Sardar Vallabhbhai Patel Memorial H.S</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>2006-2016
</div>
</div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
</div>
</div>
<!--==================== QUALIFICATION c2====================-->
<div class="q_content " data-content id="work">
<!--==================== QUALIFICATION --1====================-->
<div class="q_data">
<div>
<h3 class="q_title">Computer Communication Network and Digital Switching</h3>
<span class="q_subtitle">RTTC BSNL Mysore</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>08/07/2019- 13/07/2019
</div>
</div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
</div>
<!--==================== QUALIFICATION --2====================-->
<div class="q_data">
<div></div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
<div>
<h3 class="q_title">IOT and Computer vision</h3>
<span class="q_subtitle">The Sparks Foundation</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>26/07/2021- 21/08/2021
</div>
</div>
</div>
<!--==================== QUALIFICATION --3====================-->
<div class="q_data">
<div>
<h3 class="q_title">Electric vehicles</h3>
<span class="q_subtitle">Elite Techno Group</span>
<div class="q_cale">
<i class="uil uil-calendar-alt"></i>18/08/2021- 18/09/2021
</div>
</div>
<div>
<span class="q_round"></span>
<span class="q_line"></span>
</div>
</div>
</div>
</div>
</div>
</section>
Here is my CSS code
.skills__container{
row-gap: 0;
}
.skills__header{
display: flex;
align-items: center;
margin-bottom: var(--mb-2-5);
cursor: pointer;
}
.skills__icon,
.skills__arrow{
font-size: 2rem;
color: var(--first-color);
}
.skills__icon{
margin-right: var(--mb-0-75);
}
.skills__title{
font-size: var(--h3-font-size);
}
.skills__subtitle{
font-size: var(--small-font-size);
color: var(--text-color-light);
}
.skills__arrow{
margin-left: auto;
transition: .4s;
}
.skills__list{
row-gap: 1.5rem;
padding-left: 2.7rem;
}
.skills__title{
display: flex;
justify-content: space-between;
margin-bottom: var(--mb-0-5);
}
.skills__name{
font-size: var(--normal-font-size);
font-weight: var(--font-medium);
}
.skills__bar,
.skills__percentage{
height: 5px;
border-radius: .25rem;
}
.skills__bar{
background-color: hsl(250, 92%, 85%);
}
.skills__percentage{
display: block;
background-color: hsl(250, 69%, 61%);
}
.skills__html{ width: 90%;}
.skills__css{ width: 70%;}
.skills__bootstrap{ width: 80%;}
.skills__Angular{ width: 20%;}
.skills__java{ width: 70%;}
.skills__python{ width: 70%;}
.skills__php{ width: 5%;}
.skills__git{ width: 70%;}
.skills__sql{ width: 40%;}
.skills__agile{ width: 10%;}
.skills_close .skills__list{
height: 0;
overflow: hidden;
}
.skills_open .skills__list{
height: max-content;
margin-bottom: var(--mb-2-5);
}
.skills_open .skills__arrow{
transform: rotate(-180deg);
}
/*==================== QUALIFICATION ====================*/
.q_tabs{
display: flex;
justify-content: space-evenly;
margin-bottom: var(--mb-2);
}
.q_btn{
font-size: var(--h3-font-size);
font-weight: var(--font-medium);
cursor: pointer;
}
.q_btn:hover{
color: var(--first-color);
}
.q_icon{
font-size: 1.8rem;
margin-left: var(--mb-0-25);
}
.q_data{
display: grid;
grid-template-columns: 1fr max-content 1fr;
column-gap: 1.5rem;
}
.q_title{
font-size: var(--normal-font-size);
font-weight: var(--font-medium);
}
.q_subtitle{
display: inline-block;
font-size: var(--small-font-size);
margin-bottom: var(--mb-1);
}
.q_cale{
font-size: var(--smaller-font-size);
color: var(--text-color-light);
}
.q_round{
display: inline-block;
width: 13px;
height: 13px;
background-color: var(--first-color);
border-radius: 50%;
}
.q_line{
display: block;
width: 1.9px;
height: 100%;
background-color: var(--first-color);
transform: translate(6px, -7px);
}
.q_content[data-content]{
display: none;
}
.q_active[data-content]{
display: block;
}
.q_btn.q_active{
color: var(--first-color);
}
Here is my js code
const tabs = document.querySelectorAll('[data-target]'),
tabc = document.querySelectorAll('[data-content]');
tabs.forEach(tab =>{
tab.addEventListener('click', () =>{
const target = document.querySelector(tab.dataset.target);
tabc.forEach(tabct =>{
tabct.classList.remove('q_active');
});
target.classList.add('q_active');
tabs.forEach(tab =>{
tab.classList.remove('q_active');
});
target.classList.add('q_active');
});
});
data-target and id need to be exactly the same. You used id="Education" but data-target ='#education'. Hope this will solve your problem.

How to add Eventlisteners to all elements of a class but execute it only for a particular element during mouseover?

I've been trying to write a javascript code in which the user will be displayed three options (Purchase, Add to cart, Add to wishlists), whenever they will hover above an image of a book. The problem is that all the options for all the books are shown simultaneously when I hover above any image. Is there any way to display options only for the particular book on which the cursor is over.
let images = document.getElementsByClassName('images');
let options = document.getElementsByClassName('options');
for (const index of options)
{index.style.display = 'none';}
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseover', () => {
for (const iterator of options) {
iterator.style.display = 'inline-block';
}
});
}
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseout', () => {
for (const iterator of options) {
iterator.style.display = 'none';
}
});
}
.slider {
display: flex;
justify-content: space-between;
margin: 25px 0px;
}
.book {display: inline-block; position: relative;}
.book a {display: block; width: 20vw;}
.info {
display: block;
text-align: center;
text-decoration: none;
color: rgb(90, 90, 90);
font-size: 17px;
font-weight: 500;
transition: color 250ms;
}
.info:hover {color: rgb(255, 0, 0);}
.book a:hover {color: rgb(255, 0, 0);}
.book .info:last-of-type {margin-top: 5px;}
.book_price {text-align: center; margin: 10px 0px;}
.book_price p {
display: inline;
color: rgb(90, 90, 90);
font-size: 17px;
font-weight: 500;
margin: 10px 5px;
}
.book_price span:last-of-type p {color: rgb(255, 0, 0);}
.options {
background-color: rgba(255, 255, 255, 0.7);
display: inline-block;
position: absolute;
bottom: 250px;
right: 62px;
padding: 10px;
}
.options a {
display: inline-block;
color: rgb(90, 90, 90);
font-size: 22px;
padding: 5px 10px;
width: auto;
transition: color 250ms;
}
.options a:nth-of-type(2) {border-right: 1px solid rgb(50, 50, 50); border-left: 1px solid rgb(50, 50, 50);}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="slider">
<div class="book" class="book_1">
<img src="http://www.cliometrics.com/bbw/images/product/1.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
$10,000,000 Marraige Proposal
-James Patterson
<div class="book_price">
<span><del><p>₹200.00</p></del></span>
<span><p>₹160.00</p></span>
</div>
</div>
<div class="book" id="book_2">
<img src="http://www.cliometrics.com/bbw/images/product/2.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
How to write your first Book
-Reader's Digest
<div class="book_price">
<span><del><p>₹400.00</p></del></span>
<span><p>₹260.00</p></span>
</div>
</div>
<div class="book" class="book_3">
<img src="http://www.cliometrics.com/bbw/images/product/3.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_4">
<img src="http://www.cliometrics.com/bbw/images/product/4.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_5">
<img src="http://www.cliometrics.com/bbw/images/product/5.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_6">
<img src="http://www.cliometrics.com/bbw/images/product/6.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
</div>
You have to use the event object and the attribute target:
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseover', (event) => {
for (const iterator of options) {
event.target.style.display = 'inline-block'; // Use event.target
}
});
}

Hide element if click outside it

What I want is to close the search bar if I click anywhere but the search bar elements (input and submit button). What I made so far is use toggle to open and close it and this is working. But I couldn't find a way so far to close it if I click anywhere outside the div.
Codepen: https://codepen.io/hateusall/pen/abdedJE
HTML:
<header>
<div class="container-fluid">
<div class="navbarCustom pleft pright ">
<div class="navbar-brand">
<img src="./images/x.png" alt="x" class="header-logo">
</div>
<ul class="list-unstyled d-xl-flex align-items-center navbar-custom">
<li class="dropdown " >Lorem Ipsum</li>
<li class="dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Lorem Ipsum </li>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Lorem Ipsum</a>
<a class="dropdown-item" href="#">Lorem Ipsum</a>
<a class="dropdown-item" href="#">Lorem Ipsum</a>
</div>
<li> Lorem Ipsum</li>
<li> <button class="btn-wpp"> Whatsapp </button></li>
<li class="position-relative wrapper-bar">
<div class="search-icon search-toggler">
<i class="fas fa-search search"></i></div>
<div class="search-wrapper" >
<form action="#" class="">
<input type="text" placeholder="Search" class="search-input" id="info">
<button class="border-0 bg-dark text-white p-2 btn-search"><i class="fas fa-search" id="info2"></i></button>
</form>
</div>
</li>
</ul>
<div class="navbar-toggler text-white d-xl-none">
<span class="line line1"></span>
<span class="line line2"></span>
<span class="line line3"></span>
</div>
</div>
</div>
</header>
const searchToggler = document.querySelector(".search-toggler");
const searchWrapper = document.querySelector(".search-wrapper");
searchToggler.addEventListener("click", function(e){
if ( !$(event.target).hasClass('search-toggler')) {
$(searchWrapper).toggleClass("search-wrapper-active");
close();
}
});
function close() {
if (!$(event.target).hasClass('search-wrapper-active')) {
$(document).click(function(e){
/* here i would remove active classes */
console.log("test")
})
}
}
}
DEMO
const $toggler = $(".search-toggler");
const $wrapper = $(".search-wrapper");
$toggler.on("click", function() {
$wrapper.toggleClass("search-wrapper-active");
});
$(document).on('click', function (e) {
if ($(".search-toggler, .search-wrapper").has(e.target).length === 0) {
$wrapper.removeClass("search-wrapper-active");
}
});
You can do it like this:
[...document.querySelectorAll('body')].forEach(el => {
//get all elements in body
el.addEventListener('click', event => {
//add addEventListener
if (event.target.className.includes("search") === false) {
//if clicked element does not have class search
searchWrapper.classList.remove("search-wrapper-active");
//remove search-wrapper-active class to close it
}
})
})
And that way you don't need anything else, just combine it together to close it and open (also benefit, using only JS):
const searchWrapper = document.querySelector(".search-wrapper");
[...document.querySelectorAll('body')].forEach(el => {
el.addEventListener('click', event => {
if (event.target.className.includes("search") === false) {
searchWrapper.classList.remove("search-wrapper-active");
} else {
searchWrapper.classList.toggle("search-wrapper-active");
}
})
})
Keep in mind now:
now you have event listener on all elements on page, if you need it for something else, just expand this to suit your needs, no need to add event listener click again anywhere.
const searchWrapper = document.querySelector(".search-wrapper");
[...document.querySelectorAll('body')].forEach(el => {
el.addEventListener('click', event => {
if (event.target.className.includes("search") === false) {
searchWrapper.classList.remove("search-wrapper-active");
} else {
searchWrapper.classList.toggle("search-wrapper-active");
}
})
})
html {
height: 100%;
}
body {
min-height: 100%;
}
.search {
cursor: pointer !important;
z-index: 99999;
position: relative;
}
.search-active {
cursor: pointer;
z-index: 99999;
transition: .4s all ease-in-out;
pointer-events: all !Important;
}
.search-input {
z-index: 99999;
}
.search-image {
cursor: pointer;
z-index: 99999;
}
.search-submit {
z-index: 99999999999999999999;
cursor: pointer !important;
position: relative;
pointer-events: all !Important;
}
.toggler-image {
z-index: 9999;
position: relative;
color: #000;
}
.search-input {
border-radius: .2rem;
padding-left: 16px;
z-index: 9;
position: relative;
transition: .3s ease-in-out all;
}
.search-toggler {
z-index: 99;
position: relative;
transition: .3s ease-in-out all;
}
.search-wrapper {
opacity: 0;
pointer-events: none;
transition: .3s ease-in-out all;
position: absolute;
}
.search-wrapper-active {
transform: translateY(35px);
pointer-events: all;
opacity: 1;
transition: .3s ease-in-out all;
}
.btn-search {
position: absolute;
left: 100%;
height: 45px;
width: 50px;
}
header {
background-color: #000;
width: 100vw;
padding: 32px 0px;
}
.pleft {
padding-left: 380px;
}
.custom-cont {
padding-left: 380px;
padding-right: 280px;
}
.pright {
padding-right: 280px;
}
.navbarCustom {
display: flex;
align-items: center;
justify-content: space-between;
}
header li {
color: #fff;
margin-right: 49px;
font-size: 16px;
font-family: var(--mbold);
cursor: pointer;
}
header li:hover {
color: #4aba58;
transition: .3s;
}
header ul {
margin-bottom: 0;
}
.btn-wpp {
background-color: #4aba58;
border: none;
padding: 17px 21px;
font-size: 16px;
color: #fff;
border-radius: .4rem;
transition: .4s;
}
.btn-wpp:hover {
filter: brightness(120%);
transition: .4s;
}
.cart-value {
background-color: var(--verdeClaro);
width: 20px;
height: 20px;
display: block;
position: absolute;
top: 0;
right: 0;
text-align: center;
border-radius: 50%;
font-size: 13px;
transform: translate(80%, -80%);
}
.cart-value:hover {
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<section class="wrapper">
<header>
<div class="container-fluid">
<div class="navbarCustom pleft pright ">
<div class="navbar-brand">
<img src="./images/x" alt="x" class="header-logo">
</div>
<ul class="list-unstyled d-xl-flex align-items-center navbar-custom">
<li class="dropdown ">Lorem </li>
<li class="dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Lorem Ipsum </li>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Lorem Ipsum</a>
<a class="dropdown-item" href="#">Lorem Ipsum</a>
<a class="dropdown-item" href="#">Lorem Ipsum</a>
</div>
<li> Lorem </li>
<li> <button class="btn-wpp"> Whatsapp </button></li>
<li class="position-relative wrapper-bar">
<div class="search-icon search-toggler">
<i class="fas fa-search search">toggler</i> </div>
<div class="search-wrapper">
<form action="#" class="">
<input type="text" placeholder="Pesquisar" class="search-input" id="info">
<button class="border-0 bg-dark text-white p-2 btn-search"><i class="fas fa-search" id="info2"></i></button>
</form>
</div>
</li>
<li class="cart position-relative">
<div class="cart-value">1</div>
<img src=".//images/carrinho.png" alt="">
</li>
</ul>
<div class="navbar-toggler text-white d-xl-none">
<span class="line line1"></span>
<span class="line line2"></span>
<span class="line line3"></span>
</div>
</div>
</div>
</header>
<h1>TEST
<h1>

How to create a polling system in HTML for a movie review website?

How do I creating a voting system that uses checkboxes for 1 star, 2 stars, 3 stars, 4 stars and 5 stars. According to what the user picks it will generate an average user rating from the given votes and display the number of stars required.
I am not sure where exactly to start in terms of gathering the input from the user etc...This is all the code I have for now
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Font Awesome Icon Library -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
* {
box-sizing: border-box;
}
body {
font-family: Arial;
margin: 0 auto; /* Center website */
max-width: 800px; /* Max width */
padding: 20px;
}
.heading {
font-size: 25px;
margin-right: 25px;
}
.fa {
font-size: 25px;
}
.checked {
color: orange;
}
/* Three column layout */
.side {
float: left;
width: 15%;
margin-top:10px;
}
.middle {
margin-top:10px;
float: left;
width: 70%;
}
/* Place text to the right */
.right {
text-align: right;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The bar container */
.bar-container {
width: 100%;
background-color: #f1f1f1;
text-align: center;
color: white;
}
/* Individual bars */
.bar-5 {width: 60%; height: 18px; background-color: #4CAF50;}
.bar-4 {width: 30%; height: 18px; background-color: #2196F3;}
.bar-3 {width: 10%; height: 18px; background-color: #00bcd4;}
.bar-2 {width: 4%; height: 18px; background-color: #ff9800;}
.bar-1 {width: 15%; height: 18px; background-color: #f44336;}
/* Responsive layout - make the columns stack on top of each other instead of next to each other */
#media (max-width: 400px) {
.side, .middle {
width: 100%;
}
.right {
display: none;
}
}
</style>
</head>
<body>
<span class="heading">User Rating</span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<p>4.1 average based on 254 reviews.</p>
<hr style="border:3px solid #f1f1f1">
<div class="row">
<div class="side">
<div>5 star</div>
</div>
<div class="middle">
<div class="bar-container">
<div class="bar-5"></div>
</div>
</div>
<div class="side right">
<div>150</div>
</div>
<div class="side">
<div>4 star</div>
</div>
<div class="middle">
<div class="bar-container">
<div class="bar-4"></div>
</div>
</div>
<div class="side right">
<div>63</div>
</div>
<div class="side">
<div>3 star</div>
</div>
<div class="middle">
<div class="bar-container">
<div class="bar-3"></div>
</div>
</div>
<div class="side right">
<div>15</div>
</div>
<div class="side">
<div>2 star</div>
</div>
<div class="middle">
<div class="bar-container">
<div class="bar-2"></div>
</div>
</div>
<div class="side right">
<div>6</div>
</div>
<div class="side">
<div>1 star</div>
</div>
<div class="middle">
<div class="bar-container">
<div class="bar-1"></div>
</div>
</div>
<div class="side right">
<div>20</div>
</div>
</div>
</body>
</html>
Usually a 5-star polling system will require a database and a backend programming language. i.e. Mysql and PHP.
Here is an example:
https://www.script-tutorials.com/how-to-create-own-voting-system/

Categories

Resources