My HTML code has the following structure:
<a class='card'...<a/>
<div id = "divone" class="card__background" ... </div>
with four respective cards.
When one of the divs with class='card' is clicked. The JavaScript code is supposed to hide the 'class="card__background" inside the other class='card' divs. I already have a script code that doesn't work.
Why would that be?
I am looking to fix my JavaScript code to make it work
function imagechange(divid) {
var x = document.getElementById(divid);
if (x == "divone") {
x.style.display = "block";
divtwo.style.display = 'none';
divthree.style.display = 'none';
divfour.style.display = 'none';
} else if (x == "divtwo";) {
x.style.display = "block";
divone.style.display = 'none';
divthree.style.display = 'none';
divfour.style.display = 'none';
} else if (x == "divthree";) {
x.style.display = "block";
divone.style.display = 'none';
divtwo.style.display = 'none';
divfour.style.display = 'none';
} else {
x.style.display = "block";
divone.style.display = 'none';
divtwo.style.display = 'none';
divthree.style.display = 'none';
}
}
:root {
--background-dark: #2d3548;
--text-light: rgba(255, 255, 255, 0.6);
--text-lighter: rgba(255, 255, 255, 0.9);
--spacing-s: 8px;
--spacing-m: 16px;
--spacing-l: 24px;
--spacing-xl: 32px;
--spacing-xxl: 64px;
--width-container: 1200px;
}
* {
border: 0;
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
font-family: 'Montserrat', sans-serif;
font-size: 14px;
}
body {
height: 100%;
}
.hero-section {
align-items: flex-start;
background-image: linear-gradient(15deg, #0f4667 0%, #2a6973 150%);
display: flex;
min-height: 100%;
justify-content: center;
padding: var(--spacing-xxl) var(--spacing-l);
}
.card-grid {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-column-gap: var(--spacing-l);
grid-row-gap: var(--spacing-l);
max-width: var(--width-container);
width: 100%;
}
#media(min-width: 540px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
#media(min-width: 960px) {
.card-grid {
grid-template-columns: repeat(4, 1fr);
}
}
.card {
list-style: none;
position: relative;
}
.card:before {
content: '';
display: block;
padding-bottom: 150%;
width: 100%;
}
.card__background {
background-size: cover;
background-position: center;
border-radius: var(--spacing-l);
bottom: 0;
filter: brightness(0.75) saturate(1.2) contrast(0.85);
left: 0;
position: absolute;
right: 0;
top: 0;
transform-origin: center;
trsnsform: scale(1) translateZ(0);
transition: filter 200ms linear, transform 200ms linear;
}
.card:hover .card__background {
transform: scale(1.05) translateZ(0);
}
.card-grid:hover>.card:not(:hover) .card__background {
filter: brightness(0.5) saturate(0) contrast(1.2) blur(20px);
}
.card__content {
left: 0;
padding: var(--spacing-l);
position: absolute;
top: 0;
}
.card__category {
color: var(--text-light);
font-size: 0.9rem;
margin-bottom: var(--spacing-s);
text-transform: uppercase;
}
.card__heading {
color: var(--text-lighter);
font-size: 1.9rem;
text-shadow: 2px 2px 20px rgba(0, 0, 0, 0.2);
line-height: 1.4;
word-spacing: 100vw;
}
<body>
<center>
<h1>My Favorite Things</h1>
<h2>Click on one to get started</h2>
</center>
<section class="hero-section">
<div class="card-grid">
<a class="card" onclick="imagechange('divone')" href="#">
<div id="divone" class="card__background" style="background-image: url(photo-one.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #1</p>
<h3 class="card__heading">Photo</h3>
</div>
</a>
<a class="card" onclick="imagechange('divtwo')" href="#">
<div id="divtwo" class="card__background" style="background-image: url(photo-two.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #2</p>
<h3 class="card__heading">Drawing</h3>
</div>
</a>
<a class="card" onclick="imagechange('divthree')" href="#">
<div id="divthree" class="card__background" style="background-image: url(photo-three.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #3</p>
<h3 class="card__heading">Sports & Lifting</h3>
</div>
</a>
<a class="card" onclick="imagechange('divfour')" href="#">
<div id="divfour" class="card__background" style="background-image: url(photo-four.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #4</p>
<h3 class="card__heading">Anime & Peaky Blinders</h3>
</div>
</a>
<div>
</section>
</body>
When you use var x = document.getElementById(divid); you are getting an object. So your condition never going to be true.
If you want to check the id just change condition to:
function imagechange(divid) {
const x = document.getElementById(divid)
const id = x.id
if (id === 'divone') {
x.style.display = 'block'
divtwo.style.display = 'none'
divthree.style.display = 'none'
divfour.style.display = 'none'
}
else if (id === 'divtwo') {
x.style.display = 'block'
divone.style.display = 'none'
divthree.style.display = 'none'
divfour.style.display = 'none'
}
else if (id === 'divthree') {
x.style.display = 'block'
divone.style.display = 'none'
divtwo.style.display = 'none'
divfour.style.display = 'none'
}
else {
x.style.display = 'block'
divone.style.display = 'none'
divtwo.style.display = 'none'
divthree.style.display = 'none'
}
}
1 - Please avoid using scripts straight in your HTML, this leads to unorganized code, with a horrible structure, and pessible for maintence.
2 - I deleted the code in the script tags and in place put
<script src="./site.js"></script>
In the same folder. Create a js file correspondent to the name of your html, in this case I used 'site.js'.
3- Use this code in your 'site.js' file.
var cards = ["card1", "card2", "card3", "card4"]
var divs = ["div1", "div2", "div3", "div4"]
cards.forEach(function (card, i){
document.getElementById(card).addEventListener('click', function(){
document.getElementById(divs[i]).style.display = 'block'
for (let j in divs){
if (i != j) document.getElementById(divs[j]).style.display = 'none'
}
})
})
4 - Delete all the onclick="imagechange()" of your card class tags and add id for them.
5 - Your HTML will be like this:
<body>
<center>
<h1>My Favorite Things</h1>
<h2>Click on one to get started</h2>
</center>
<section class="hero-section">
<div class="card-grid">
<a id = "card1" class="card" href="#">
<div id = "div1" class="card__background" style="background-image: url(photo-one.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #1</p>
<h3 class="card__heading">Photo</h3>
</div>
</a>
<a id = "card2" class="card" href="#">
<div id = "div2" class="card__background" style="background-image: url(photo-two.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #2</p>
<h3 class="card__heading">Drawing</h3>
</div>
</a>
<a id = "card3" class="card" href="#">
<div id = "div3" class="card__background" style="background-image: url(photo-three.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #3</p>
<h3 class="card__heading">Sports & Lifting</h3>
</div>
</a>
<a id = "card4" class="card" href="#">
<div id = "div4" class="card__background" style="background-image: url(photo-four.jpg)"></div>
<div class="card__content">
<p class="card__category">FAV #4</p>
<h3 class="card__heading">Anime & Peaky Blinders</h3>
</div>
</a>
<div>
</section>
<script src="./site.js"></script>
</body>
Related
I'm a beginner in javascript so I'm still learning but I have the impression that my code is too repetitive but I don't know how to improve it, moreover I try to apply the same code to the same html element which have the same id or the same class but it doesn't work every time it applies only to the first element.
Thanks in advance to those who will help me.
<body>
<section>
<div id="prj1" class="projet-contain">
<div class="preview">
<a >Projet Convertigo</a>
<img class="arrow-down" src="images/down-arrow-svgrepo-com.svg">
<img src="images/Convertigo.png" class="convertigo" alt="">
</div>
<div id="projet1">
<a>c'est la div 1</a>
</div>
</div>
<div id="prj2" class="projet-contain">
<div class="preview">
<a >Projet Convertigo</a>
<img class="arrow-down" src="images/down-arrow-svgrepo-com.svg">
<img src="images/Convertigo.png" class="convertigo" alt="">
</div>
<div id="projet2">
<a>c'est la div 2</a>
</div>
</div>
<div id="prj3" class="projet-contain">
<div class="preview">
<a >Projet Convertigo</a>
<img class="arrow-down" src="images/down-arrow-svgrepo-com.svg">
<img src="images/Convertigo.png" class="convertigo" alt="">
</div>
<div id="projet3">
<a>c'est la div 3</a>
</div>
</div>
</section>
</body>
<style> .projet-contain{
display: flex;
flex-direction: column;
margin-bottom: 50px;
width: auto;
height: auto;
background: radial-gradient(circle, rgba(238,174,202,0.200) 0%, rgba(148, 188, 233, 0.200) 100%);;
border-radius: 10px 10px 10px 10px;
padding: 10px;
user-select: none;
}
.preview{
display: flex;
justify-content: space-between;
align-items: center;
}
section >div>div >a {
text-decoration: none;
color: white;
}
.convertigo{
width: 10vw;
}
.arrow-down {
transition: transform 0.5s;
width: 1.5vw;
-webkit-filter: invert(100%); /* safari 6.0 - 9.0 */
filter: invert(100%);
}
.rotate-arrow {
transform: rotate(180deg);
}
</style>
<script>
const projet1 = document.getElementById("projet1");
const projet2 = document.getElementById("projet2");
const projet3 = document.getElementById("projet3");
const prj = document.getElementById("prj");
var arrow = document.querySelectorAll(".arrow-down")[0]
projet1.style.display = "none";
projet2.style.display = "none";
projet3.style.display = "none";
prj1.onclick = function () {
if (projet1.style.display !== "none") {
projet1.style.display = "none";
arrow.classList.toggle('rotate-arrow')
} else {
projet1.style.display = "flex";
arrow.classList.toggle('rotate-arrow')
}
console.log("prj1");
};
prj2.onclick = function () {
if (projet2.style.display !== "none") {
projet2.style.display = "none";
arrow.classList.toggle('rotate-arrow')
} else {
projet2.style.display = "flex";
arrow.classList.toggle('rotate-arrow')
}
console.log("prj2");
};
prj3.onclick = function () {
if (projet3.style.display !== "none") {
projet3.style.display = "none";
arrow.classList.toggle('rotate-arrow')
} else {
projet3.style.display = "flex";
arrow.classList.toggle('rotate-arrow')
}
console.log("pr3");
};
</script>
I have in my beacon <div class="post">
another beacon <p class="compteur"></p>
which is intended to be incremented to find out if the user likes (clicks) it or decrements it if the user likes (clicks) it.
for this reason I use a boolean to check the condition
in my js I have a function that its charge of the fact
but as I apply this function to multiple tag recovers in my code they all act on the same boolean and value that causes me problem.
I would like each of them to be independent
const cerle = document.getElementsByClassName('cerle')
const compteur = document.getElementsByClassName('compteur')
let onOff = false;
let nbr = 0;
function compte (i) {
if (onOff == false) {
nbr++
console.log( nbr);
onOff= true;
console.log( onOff);
compteur[i].innerHTML=`${nbr}k`
}else if(onOff == true){
nbr--
console.log( nbr);
onOff= false;
console.log( onOff);
compteur[i].innerHTML=`${nbr}k`
}
}
for (let i = 0; i < cerle.length; i++) {
cerle[i].addEventListener("click",()=>{
compte (i);
});
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Nunito Sans', sans-serif;
}
.contain{
align-items: center;
display: flex;
flex-direction: row;
width: 100%;
height: 400px;
background-color: yellowgreen;
}
.post{
margin-left: 30px;
width: 30%;
height: 70%;
background-color: rgb(73, 50, 205);
}
.cerle{
width: 20%;
height: 30%;
border-radius: 50%;
background-color: rgb(205, 35, 35);
}
<body>
<div class="contain">
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
</div>
</body>
well here I was able to solve my problem and thank you to everyone who kindly helped me
I went through creating a new object for the assigned to each recovered div only the js file changed.
Here's my code.
const cerle = document.querySelectorAll(".cerle");
const compteur = document.getElementsByClassName('compteur');
let etat = false;
var valeurDesPoste = new Array();
class compte {
constructor(onOff, valeur ,i) {
this.onOff = onOff;
this.valeur = valeur;
this.i = i;
}
teste() {
if (this.onOff == false) {
this.valeur++ ;
console.log( this.valeur);
this.onOff= true;
console.log( this.onOff);
compteur[this.i].innerHTML=`${this.valeur}k`
}else if(this.onOff == true){
this.valeur-- ;
console.log( this.valeur);
this.onOff= false;
console.log( this.onOff);
compteur[this.i].innerHTML=`${this.valeur}k`
}
}
}
for (let i = 0; i < cerle.length; i++) {
valeurDesPoste.push(50 *i);
// console.log( valeurDesPoste[i]);
let a =new compte(etat, valeurDesPoste[i] ,i);
cerle[i].addEventListener("click",()=>{
a.teste()
});
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Nunito Sans', sans-serif;
}
.contain{
align-items: center;
display: flex;
flex-direction: row;
width: 100%;
height: 400px;
background-color: yellowgreen;
}
.post{
margin-left: 30px;
width: 30%;
height: 70%;
background-color: rgb(73, 50, 205);
}
.cerle{
width: 20%;
height: 30%;
border-radius: 50%;
background-color: rgb(205, 35, 35);
}
<div class="contain">
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
<div class="post">
<div class="cerle"></div>
<p class="compteur"></p>
</div>
</div>
How can I make the red backgrounded "Content" area open smoothly from top to bottom when click to "Clicker" with this piece of code? And extra question is, how can I add more Clickers in the same Html with the same javascript code? If I duplicate these, only one is working.
function myFunction() {
var x = document.getElementById("myLinks");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
.accordion {
position: relative;
width: 100%;
height: auto;
background:red;
}.grider{
display: block;
width: 100%;
background: #fff;
}
#myLinks {
display:none;
}
.content {
height:50px;}
<div class="accordion">
<a href="javascript:void(0);" onclick="myFunction()" class="grider clearfix toggle">
<span>Clicker</span>
</a>
<div class="content clearfix" id="myLinks">Content</div>
</div>
You don't need Javascript for all animations. Why don't you try with CSS?
const btns = document.querySelectorAll('.btn-dropdown')
btns.forEach(btn => {
btn.addEventListener('click', function(e) {
e.target.classList.toggle('open')
})
})
html,
body {
margin: 0;
font-family: Arial;
}
nav {
display: flex;
}
.btn-dropdown {
position: relative;
cursor: pointer;
padding: 8px 16px;
border: 1px solid gray;
}
.dropdown-content-container {
overflow-y: hidden;
max-height: 0;
transition: all 0.25s;
}
.btn-dropdown.open>.dropdown-content-container {
max-height: 120px;
transition: all 0.4s;
}
<nav>
<div class="dropdown-wrapper">
<div class="btn-dropdown">
CLICK 1
<div class="dropdown-content-container">
<div class="dropdown-content">
DROPDOWN CONTENT 1
</div>
</div>
</div>
</div>
<div class="dropdown-wrapper">
<div class="btn-dropdown">
CLICK 2
<div class="dropdown-content-container">
<div class="dropdown-content">
DROPDOWN CONTENT 2.1<br /> DROPDOWN CONTENT 2.2<br /> DROPDOWN CONTENT 2.3<br /> DROPDOWN CONTENT 2.4<br />
</div>
</div>
</div>
</div>
</nav>
I've coded some tabs and it seems to work well, although I'm sure I can achieve this with much cleaner code! I'm just not sure how to do that at the moment. I would really appreciate some help with this one.
I'm not sure if its loops I want to use or something completely different?
The way I've done it obviously works but it just seem unnecessary and messy, after this the next step is to add in a transition effect as the tabs come down. I'm not sure if this will even allow me to do that.
function myFunction() {
var a = document.getElementById("results1");
var b = document.getElementById("results2");
var c = document.getElementById("results3");
var d = document.getElementById("title1");
var e = document.getElementById("title2");
var f = document.getElementById("title3");
if (a.style.display === "none") {
a.style.display = "block";
b.style.display = "none";
c.style.display = "none";
d.style.backgroundColor = "#005FAA";
e.style.backgroundColor = "lightgrey";
f.style.backgroundColor = "lightgrey";
}
else {
a.style.display = "none";
d.style.backgroundColor = "lightgrey";
}
}
function myFunction1() {
var a = document.getElementById("results1");
var b = document.getElementById("results2");
var c = document.getElementById("results3");
var d = document.getElementById("title1");
var e = document.getElementById("title2");
var f = document.getElementById("title3");
if (b.style.display === "none") {
a.style.display = "none";
b.style.display = "block";
c.style.display = "none";
d.style.backgroundColor = "lightgrey";
e.style.backgroundColor = "#005FAA";
f.style.backgroundColor = "lightgrey";
}
else {
b.style.display = "none";
e.style.backgroundColor = "lightgrey";
}
}
function myFunction2() {
var a = document.getElementById("results1");
var b = document.getElementById("results2");
var c = document.getElementById("results3");
var d = document.getElementById("title1");
var e = document.getElementById("title2");
var f = document.getElementById("title3");
if (c.style.display === "none") {
a.style.display = "none";
b.style.display = "none";
c.style.display = "block";
d.style.backgroundColor = "lightgrey";
e.style.backgroundColor = "lightgrey";
f.style.backgroundColor = "#005FAA";
}
else {
c.style.display = "none";
f.style.backgroundColor = "lightgrey";
}
}
body{
margin: 10px;}
.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}
.title:last-child{
margin-right:0px;
width:32%;}
.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
<div id="title1" class="title" onclick="myFunction()">
<h4>Item 1</h4>
</div>
<div id="title2" class="title" onclick="myFunction1()">
<h4>Item 2</h4>
</div>
<div id="title3" class="title" onclick="myFunction2()">
<h4>Item 3</h4>
</div>
</div>
<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
Maybe something like this? You are already using JQuery, so maybe make it modular and use it to help with your transition down effects (you can transition them up too if you'd like).
const tabs = {
animating: false,
toggleResults: function(thatTab) {
const thatResult = $(`[data-title="${thatTab.attr('id')}"]`);
thatTab.toggleClass('activeTab');
thatResult.toggleClass("openedResult");
tabs.animating = true;
thatResult.slideToggle("fast", function() {
tabs.animating = false;
});
},
init: function() {
$(".title").click(function() {
const thatTab = $(this);
const openedResult = $('.openedResult');
const thatTabId = thatTab.attr("id");
const openedResultTitle = openedResult.data('title');
if (!tabs.animating) {
$('.activeTab').removeClass('activeTab');
openedResult.removeClass('openedResult').hide();
if (thatTabId !== openedResultTitle) {
tabs.toggleResults(thatTab);
}
}
});
}
};
$(function() {
tabs.init();
});
body {
margin: 0;
}
.container {
display: flex;
justify-content: space-between;
width: 100%;
}
.title {
background-color: lightgrey;
flex-basis: 32%;
transition: background-color 0ms;
text-align: center;
color: white;
padding: 30px;
box-sizing: border-box;
}
.activeTab {
background-color: #005faa;
transition: background-color 100ms;
}
.results {
background-color: #005faa;
display: none;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div id="title1" class="title">
<h4>Item 1</h4>
</div>
<div id="title2" class="title">
<h4>Item 2</h4>
</div>
<div id="title3" class="title">
<h4>Item 3</h4>
</div>
</div>
<div class="results" data-title="title1">Item 1</div>
<div class="results" data-title="title2">Item 2</div>
<div class="results" data-title="title3">Item 3</div>
Try this , you can call same function on all three divs with passing their ids to find the current id.
<!DOCTYPE html>
<style type="text/css">
body{
margin: 10px;}
.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}
.title:last-child{
margin-right:0px;
width:32%;}
.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
.active{
display = "block"
}
.inactive{
display : "none"
backgroundColor:"#005FAA"
}
</style>
<div class="container">
<div id="title1" class="title" onclick="ActivateTab(1)">
<h4>Item 1</h4>
</div>
<div id="title2" class="title" onclick="ActivateTab(2)">
<h4>Item 2</h4>
</div>
<div id="title3" class="title" onclick="ActivateTab(3)">
<h4>Item 3</h4>
</div>
<button onclick="ActivateTab(2)">Test</button>
</div>
<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
<script>
function ActivateTab(id){
let results = document.querySelectorAll(".results")
let titles = document.querySelectorAll(".title")
results.forEach((elementResut,index) =>{
let elementTitle = titles[index];
if(elementResut.id === "results"+id
&& elementResut.style.display === "none")
{
elementResut.style.display = "block";
elementTitle.style.backgroundColor = "#005FAA";
}
else{
elementResut.style.display = "none";
elementTitle.style.backgroundColor = "lightgrey";
}
});
}
</script>
Here is one possible clean-up:
function myFunction(title) {
var results = [...document.getElementsByClassName("results")]
results.forEach(function(r) {
if (title.dataset.for == r.id) {
r.style.display = "block";
} else {
r.style.display = "none";
}
});
var titles = [...document.getElementsByClassName("title")]
titles.forEach(function(t) {
if (t == title) {
t.style.backgroundColor = "#005FAA"
} else {
t.style.backgroundColor = "lightgrey"
}
});
}
body{
margin: 10px;}
.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}
.title:last-child{
margin-right:0px;
width:32%;}
.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
<div id="title1" data-for="results1" class="title" onclick="myFunction(this)">
<h4>Item 1</h4>
</div>
<div id="title2" data-for="results2" class="title" onclick="myFunction(this)">
<h4>Item 2</h4>
</div>
<div id="title3" data-for="results3" class="title" onclick="myFunction(this)">
<h4>Item 3</h4>
</div>
</div>
<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
I replaced your three functions with one function that accepts a parameter representing the title element. In the event handler, we just pass this to that function. Then in the function, we loop over the things that might have to change (the title and results nodes) testing as we do whether we're working with the matching element or a different one and choosing behavior based on that.
To link the title elements with the results one, I add a data-for attribute to it. There are many other ways this could be done, including using regular expressions to find the basic id (title2 ~> 2, results2 ~> 2 for instance) and matching on those. But this should get you going.
There is more clean-up I would probably do on this, but this should offer significant simplification.
Update
A comment pointed out that the above did not allow for total tab deselection. Given that, it seems better to refactor a bit more and use the shared base id approach. Here is another version written that way:
function myFunction(title) {
var id = title.id.match(/^\D*(\d+)$/)[1]
var hidden = document.getElementById(`results${id}`).style.display !== 'block';
[...document.getElementsByClassName("results")].forEach(function(r) {
r.style.display = "none";
});
[...document.getElementsByClassName("title")].forEach(function(t) {
t.style.backgroundColor = "lightgrey";
});
if (hidden) {
document.getElementById(`results${id}`).style.display = 'block';
document.getElementById(`title${id}`).style.backgroundColor = '#005FAA';
}
}
body{
margin: 10px;}
.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}
.title:last-child{
margin-right:0px;
width:32%;}
.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
<div id="title1" class="title" onclick="myFunction(this)">
<h4>Item 1</h4>
</div>
<div id="title2" class="title" onclick="myFunction(this)">
<h4>Item 2</h4>
</div>
<div id="title3" class="title" onclick="myFunction(this)">
<h4>Item 3</h4>
</div>
</div>
<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
I need help to do a simple text slider in jQuery or JavaScript.
I need a slider with animation so that the text moves from right to left.
Within my code I have also pagination, where I need highlight which text is active.
This is all of what I have, I need to be very simple.
All answers on the internet are so complicated.
Can someone help me?
.active{
color:red;
}
<div class="buttons">
<button name="prev">Prev</button>
<button name="next">Next</button>
</div>
<div class="content">
<div class="slide">
<p>content od slide</p>
</div>
<div class="slide">
<p>content od slide</p>
</div>
<div class="slide">
<p>content od slide</p>
</div>
</div>
<div class="paginator">
<div class="pagin-tracker">1</div>
<div class="pagin-tracker active">1</div>
<div class="pagin-tracker">1</div>
</div>
You can try this one.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.slider {
}
.slider__wrap {
overflow: hidden;
}
.slide {
width: 100%;
display: inline-block;
text-align: center;
}
.content {
will-change: transform;
white-space: nowrap;
transition: transform 0.3s;
}
</style>
</head>
<body>
<div id="slider" class="slider">
<div class="buttons">
<button name="prev">Prev</button>
<button name="next">Next</button>
</div>
<div class="slider__wrap">
<div class="content" style="transform: translate(-100%);" data-active="1"> <!-- if you need to set initial position to the second slider, or you can use translate(0) to set it to the first slide -->
<div class="slide">
<p>content od slide 1</p>
</div>
<div class="slide">
<p>content od slide 2</p>
</div>
<div class="slide">
<p>content od slide 3</p>
</div>
</div>
</div>
<div class="paginator">
<div class="pagin-tracker">1</div>
<div class="pagin-tracker active">1</div>
<div class="pagin-tracker">1</div>
</div>
</div>
<script>
const slider = document.getElementById('slider');
const sliderWrap = slider.querySelector('.slider__wrap');
const sliderContent = sliderWrap.querySelector('.content');
const sliderButtons = slider.querySelector('.buttons');
const buttonPrev = sliderButtons.querySelector('button[name="prev"]');
const buttonNext = sliderButtons.querySelector('button[name="next"]');
const pages = Array.from(slider.querySelectorAll('.pagin-tracker'));
const pagesCount = pages.length;
const slidesCount = sliderContent.querySelectorAll('.slide').length;
let activeIndex = sliderContent.getAttribute('data-active');
const updatePaginator = () => {
for (let i = 0; i < pagesCount; i++) {
pages[i].classList.remove('active');
}
if (pages[activeIndex]) {
pages[activeIndex].classList.add('active');
}
};
const applyStyle = () => {
sliderContent.setAttribute('data-active', activeIndex);
sliderContent.style.cssText = `transform: translate(-${activeIndex * 100}%);`;
updatePaginator();
};
buttonPrev.addEventListener('click', () => {
if (activeIndex > 0) {
activeIndex--;
applyStyle();
}
}, false);
buttonNext.addEventListener('click', () => {
if (activeIndex < slidesCount - 1) {
activeIndex++;
applyStyle();
}
}, false);
</script>
</body>
</html>
You can use something like this and extend as per you requirement.
https://codepen.io/anon/pen/MqRpKg
HTML
<div class="slide-wrap">
<div class="slide-mask">
<ul class="slide-group">
<li class="slide">this</li>
<li class="slide">is</li>
<li class="slide">a</li>
<li class="slide">simple</li>
<li class="slide">slider</li>
</ul>
</div>
<div class="slider-nav">
<ul></ul>
</div>
</div>
JQuery:
var $slide = $('.slide'),
$slideGroup = $('.slide-group'),
$bullet = $('.bullet')
var slidesTotal = ($slide.length - 1),
current = 0,
isAutoSliding = true;
$bullet.first().addClass('current');
var clickSlide = function() {
//stop auto sliding
window.clearInterval(autoSlide);
isAutoSliding = false;
var slideIndex = $bullet.index($(this));
updateIndex(slideIndex);
};
var updateIndex = function(currentSlide) {
if(isAutoSliding) {
if(current === slidesTotal) {
current = 0;
} else {
current++;
}
} else {
current = currentSlide;
}
$bullet.removeClass('current');
$bullet.eq(current).addClass('current');
transition(current);
};
var transition = function(slidePosition) {
var slidePositionNew = (slidePosition ) * 500;
$slideGroup.animate({
'left': '-' + slidePositionNew + 'px'
});
};
var autoSlide = window.setInterval(updateIndex, 2000);
$( "li.slide" ).each(function( index ) {
$('.slider-nav').append('<span class="bullet">'+index+'</span>');
});
var $bullet = $('.bullet');
$bullet.on( 'click', clickSlide);
CSS
body {
background: rgb(191, 76, 76);
}
/* slider
----------------------*/
.slide-wrap {
margin: 5% auto 0;
width: 540px;
}
.slide-mask {
position: relative;
overflow: hidden;
height: 100px;
}
.slide-group {
position: absolute;
top: 0px;
left: 0;
}
.slide {
display:inline-block;
height: 100px;
width:500px;
font: 100 90px/135px "lato";
font-size: 2em;
color: #fff;
text-align: center;
text-transform: uppercase;
}
/* nav
----------------------*/
.slide-nav {
text-align: center;
border: 1px solid red;
height: 30px;
color: red;
}
.slide-nav ul {
margin: 0;
padding: 0;
}
.slide-nav li {
border: 1px solid red;
width: 100px;
cursor: pointer;
color: red;
}
.slide-nav li.current {
background: rgb(144, 39, 39);
}
.slider-nav {
width: 300px;
text-alignt: center;
margin-left:40%;
}
span.bullet {
display:inline-block;
width: 30px;
cursor: pointer;
}