I have built a slider with jQuery. But there is still a thing missing, I want indicators so the user can switch between the images. This should be possible through the .bullet-points and the .thumbnails img
I don't really find an approach with my special markup, how can I do that?
Here is the code
https://codepen.io/Insane415/pen/yXboEV
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var backgrounds = ["blue", "yellow", "green", "grey"];
i = 1;
var time = 3000;
setInterval(function() {
if (i != 0) {
images[i - 1].removeClass("active");
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
}
if (i == images.length) {
i = 0
}
images[i].addClass("active");
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
$(".slider").css("background-color", backgrounds[i]);
i++;
}, time);
});
.text-holder p {
margin: 0;
}
.slider {
padding: 20px;
margin: 50px;
/*background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHzNrZnq-4-FItozqSu2ZWCBXW4LjWKTlkOOgDlZFj-JtdTuclVQ');*/
background-color: blue;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.thumbnails {
height: 100%;
}
.thumbnails img {
max-width: 50px;
display: block;
margin-bottom: 10px;
}
.text-holder .text {
display: none;
}
/*display active image*/
.active {
display: block!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail {
display: none!important;
}
.bullet-points {
display: block;
text-align: center;
}
.bullet-points a {
font-size: 30px;
text-decoration: none;
color: inherit;
}
/*.image-holder{
max-width: 350px!important;
}
.image-holder img{
max-width: 350px!important;
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<div class="slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" style="display:none;" class="active">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg" style="display:none;">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg" style="display:none;">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg" style="display:none;">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-2">
<div class="thumbnails">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active-thumbnail">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
</div>
<div class="col-md-6">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h1>Giant Heading 1</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 2</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 3</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 4</h1>
<p>Some more text</p>
</div>
</div>
</div>
</div>
</div>
</div>
You can try something like this.
Create a slider function instead of using as an anonymous function like in your current code.
Bind an on click event to the .thumbnails img and .bullet-points a and you can control the logic in that event.
Create a variable to control current slide so when user jumping from slide to slide, the slideshow shows correctly.
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var backgrounds = ["blue", "yellow", "green", "grey"];
var i = 0;
var currentSlide = 0;
var time = 3000;
var sliderTimer = setInterval(slider, time);
// slider navigation
$('.bullet-points a, .thumbnails img').click(function(e) {
e.preventDefault();
var pos = $(this).index();
clearInterval(sliderTimer); // stop auto slideshow
sliderTimer = false;
slider(pos);
});
function slider(pos) {
currentSlide = i;
if (typeof(pos) !== 'undefined') {
i = pos;
images[currentSlide - 1].removeClass("active");
text[currentSlide - 1].removeClass("active");
thumbnails[currentSlide - 1].removeClass("active-thumbnail");
}
if (i != 0) {
images[i - 1].removeClass("active");
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
}
if (i == images.length) { i = 0 }
images[i].addClass("active");
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
$(".slider").css("background-color", backgrounds[i]);
i++;
if (!sliderTimer) {
sliderTimer = setInterval(slider, time); // start auto slideshow
}
}
});
.text-holder p{margin: 0;}
.slider{
padding:20px;
margin: 50px;
/*background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHzNrZnq-4-FItozqSu2ZWCBXW4LjWKTlkOOgDlZFj-JtdTuclVQ');*/
background-color: blue;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.thumbnails{
height: 100%;
}
.thumbnails img{
max-width: 50px;
display: block;
margin-bottom: 10px;
}
.text-holder .text{
display: none;
}
/*display active image*/
.active{
display: block!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail{
display: none!important;
}
.bullet-points{
display: block;
text-align: center;
}
.bullet-points a{
font-size: 30px;
text-decoration: none;
color: inherit;
}
/*.image-holder{
max-width: 350px!important;
}
.image-holder img{
max-width: 350px!important;
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" style="display:none;" class="active">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg" style="display:none;">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg" style="display:none;">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg" style="display:none;">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-2">
<div class="thumbnails">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active-thumbnail">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
</div>
<div class="col-md-6">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h1>Giant Heading 1</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 2</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 3</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 4</h1>
<p>Some more text</p>
</div>
</div>
</div>
</div>
</div>
</div>
Related
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
right: 0;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
In the above code snippet, If you click on any item, then it will show a modal on the right side. As you can see, item 3 is larger in width. So if you click on item 3 then you have to scroll-right to view the modal.
So I want to show modal on mouse click position.
How can I do this?
There are at least two options
The first one will spawn the modal directly at the mouse position using JS
And the second one will spawn the modal on the left side. This can be achieved using CSS
First option
So basically you can get the mouse position and set the modal position to it.
In detail remove the top/left/right/bottom properties from the modal class in CSS (they aren't needed) and add some lines of JS.
Please write me in the comments if you want to align the modal a bit around the mouse cursor... It's just about a few numbers.
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
var rect = e.target.getBoundingClientRect(); // get some poition, scale,... properties of the item
mousePos.x = e.clientX - rect.left; // get the mouse position relative to the element
mousePos.y = e.clientY - rect.top;
item.querySelector('.modal').classList.toggle('show');
item.querySelector('.modal').style.left = mousePos.x + "px"; // set the modal position to the last stored position
item.querySelector('.modal').style.top = mousePos.y + "px";
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Second option
The second option uses basic CSS to align the modals on the left side - it is much easier to implement and you just have to remove thee left/right/top/bottom property from the modal class and add left:0:
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
left: 0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Hope I could help :D
You can change the style dynamically and get the position X of your controller, then add the style using JS code.
Also, remove the right 0 from your modal class
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').style.left = e.clientX + "px";
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
I'm not very good at css but i need to solve some alignment issues with Collapsible div. Below HTML portion is in while loop and I have multiple rows of div and each row has 2 div. When clicking on 1st div on the 1st row it is expanding and pushing down the 1st div of 2nd row which is correct but along with this 2nd div of 2nd row also moving down.
<div class="cards">
<div class="Interview" id="Interview">
<?php while ($Interview_Details) { ?>
<div class="card01">
<div class="collapsible">
<div class="image"><img src="<?php echo "/images/people/" . $Interview_Details['Photo']; ?>"/></div>
<div class="interview"><?php echo $Interview_Details['shortDesc']; ?>
</div>
</div>
<div class="content">
<p><?php echo $Interview_Details['LongDesc']; ?></p>
<div class="padding10"> </div>
</div>
</div>
<?php } ?>
</div>
</div>
.card01{
width: 47%;
height: auto;
position: relative;
display: inline-block;
margin-top: 20px;
vertical-align: top;
min-height: 220px;
background: rgb(255, 255, 255);
}
.content {
max-height: 0px;
padding: 0px 18px;
overflow: hidden;
transition: max-height 0.2s ease-out 0s;
}
<script>
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
</script>
Define a class for Expand/Collapse
CSS
.card01 .content {
height: 0;
transition: 100%;
}
.card01 .content.active {
height: auto;
}
Javascript
const cards = document.querySelectorAll("#Interview .card01")
cards.forEach(e => {
e.addEventListener("click", () => {
e.classList.toggle("active");
cards.forEach(el => {
if (el !== e) el.classList.remove("active");
});
});
});
The class card01 can only appear once per column... meaning each column has it's own container. Here is a snippet to see how the HTML should look.
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
.card01{
width: 47%;
height: auto;
position: relative;
display: inline-block;
margin-top: 20px;
vertical-align: top;
min-height: 220px;
background: rgb(255, 255, 255);
}
.content {
max-height: 0px;
padding: 0px 18px;
overflow: hidden;
transition: max-height 0.2s ease-out 0s;
}
<div class="card01">
<div class="collapsible">
<div class="image"><img src="/images/people/" /></div>
<div class="interview">This is a short description</div>
</div>
<div class="content">
<p>This is a long description. This is a long description. This is a long description</p>
<div class="padding10"> </div>
</div>
<div class="collapsible">
<div class="image"><img src="/images/people/" /></div>
<div class="interview">This is a short description</div>
</div>
<div class="content">
<p>This is a long description. This is a long description. This is a long description</p>
<div class="padding10"> </div>
</div>
</div>
<div class="card01">
<div class="collapsible">
<div class="image"><img src="/images/people/" /></div>
<div class="interview">This is a short description</div>
</div>
<div class="content">
<p>This is a long description. This is a long description. This is a long description</p>
<div class="padding10"> </div>
</div>
<div class="collapsible">
<div class="image"><img src="/images/people/" /></div>
<div class="interview">This is a short description</div>
</div>
<div class="content">
<p>This is a long description. This is a long description. This is a long description</p>
<div class="padding10"> </div>
</div>
</div>
I have the following code and I want to use ids to switch between slides, but with an id it doesn't work and als with JS scrollTo, scrollIntoView and other variations.
It works on the way down but not up.
I try to make a website which overlaps with itself and creates a nice progressive flow for surveys.
It should also be able to move to a previous slide, so you can enter or change some answer in such a survey.
I hope you can help me and maybe see something which i didn't see.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<div id="s1" class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2" class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3" class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4" class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5" class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6" class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7" class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8" class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9" class="slide">
<h1>Slide 9</h1>
</div>
</body>
</html>
After trying a long time I found a solution but it is very specific.
You need to have a parent element which only includes the slides (in this case it is main), then you need to give the parent element a height and an overflow auto.
After those steps add the javascript, which gets the selected element and its parent (here again main), then calculates the average height per element, after that it gets the index of the elem relative to the parent and multiplies it with the height to get the scrollOffset, which is in the last step set for the parent.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
window.onhashchange = function() {
let hash = document.body.querySelector(location.hash);
let parent = hash.parentElement;
let scrollOffset = parent.scrollHeight / parent.childElementCount;
scrollOffset *= Array.prototype.indexOf.call(parent.children, hash);
parent.scrollTop = scrollOffset;
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
main {
height: 100vh;
overflow: auto;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<main>
<div id="s1" class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2" class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3" class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4" class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5" class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6" class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7" class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8" class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9" class="slide">
<h1>Slide 9</h1>
</div>
</main>
</body>
</html>
Absolutely loved the implentation. Such small css and so powerful effect.
But seems like Browser don't do the # magic with sticky elements. Although this could have been solved with JS, but thought of having a HTML-CSS solution to it by a little tweak in the HTML (adding an extra static element for # reference). Hope you like the solution.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<div id="s1"> </div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 9</h1>
</div>
</body>
</html>
I am trying to build a lucky draw system. There are 8 cards in each category and 8 people to assign those cards. I want to make a flipping animation on cards that all cards flip till 10 seconds then only one card appear on screen as jackpot. How can I achieve that with CSS and JavaScript?
My current code:-
CSS
.card {
display: grid;
grid-template-columns: 300px;
float: none; /* Added */
margin-top: 50px;
border-radius: 18px;
align-content: center;
margin-left: auto;
margin-right: auto;
background-color: #FFEB3B;
box-shadow: 5px 5px 15px rgba(0,0,0,0.9);
font-family:Lucida Handwriting;
text-align: center;
transition: 0.5s ease;
cursor: pointer;
}
In current system i am loading all cards to screen. How can i make them rotate for 10 seconds and make only one card visible and other disappear on a button click.
I set the required functions. You can call them depending on the usage you want
var elems = document.getElementsByClassName('flip-box-inner');
var totalSecond = 0;
var myTimer;
function RotationCard() {
totalSecond = totalSecond + 1;
for (var i = 0; i < elems.length; i++) {
if(totalSecond == 1)
{
if(i%2 == 0)
{
if(!elems[i].classList.contains("myAnim"))
elems[i].classList.add("myAnim");
else
elems[i].classList.remove("myAnim");
}
}
else
{
if(!elems[i].classList.contains("myAnim"))
elems[i].classList.add("myAnim");
else
elems[i].classList.remove("myAnim");
}
}
if (totalSecond <= 10) {
myTimer = setTimeout(RotationCard, 1000);
}
else
{
ResetAndClearCard();
}
}
function SelectCard()
{
ResetAndClearCard();
var rand = Math.floor(Math.random() * 10) + 1;
for (var i = 0; i < elems.length; i++) {
if(rand == i)
elems[i].classList.add("myAnim");
}
}
function ResetAndClearCard()
{
totalSecond = 0;
clearTimeout(myTimer);
for (var i = 0; i < elems.length; i++) {
if(elems[i].classList.contains("myAnim"))
elems[i].classList.remove("myAnim");
}
}
body {
font-family: Arial, Helvetica, sans-serif;
text-align:center;
}
.flip-box {
background-color: transparent;
width: 300px;
height: 200px;
perspective: 1000px;
display:inline-block;
}
.flip-box-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.flip-box:hover .flip-box-inner {
transform: rotateY(180deg);
}
.flip-box-front, .flip-box-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.flip-box-front {
background-color: #bbb;
color: black;
}
.flip-box-back {
background-color: #555;
color: white;
transform: rotateY(180deg);
}
.myAnim
{
transform: rotateY(180deg);
transition: transform 0.8s;
}
.btn1
{
height:30px;
bordder:1px solid #ddd;
width:150px;
background:#228833;
color:white;
}
.btn2
{
height:30px;
bordder:1px solid #ddd;
width:150px;
background:#2233ff;
color:white;
}
.btn3
{
height:30px;
bordder:1px solid #ddd;
width:180px;
background:#ff2266;
color:white;
}
.btn1:hover,.btn2:hover,.btn3:hover
{
background:#223366;
}
<button class="btn1" onclick="RotationCard()">rotation</button>
<button class="btn2" onclick="SelectCard()">select</button>
<button class="btn3" onclick="ResetAndClearCard()">reset & clear Timer</button>
</div>
<h1>Image Flip with Text</h1>
<h3>Hover over the image below:</h3>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
<div class="flip-box">
<div class="flip-box-inner">
<div class="flip-box-front">
<img src="https://unsplash.it/1920/600?image=13" alt="Paris" style="width:300px;height:200px">
</div>
<div class="flip-box-back">
<h2>Paris</h2>
<p>What an amazing city</p>
</div>
</div>
</div>
I cant figure out hot to make a code that works, i have 4 images side by side and i need a description section under the images, this section should be hidden and when i click over an image the correct information should be displayed
<section class="img" style="text-align:center;">
<div class="container" onclick="select(1)" onclick="hideunhide()"">
<img src="img/1.jpg">
</div>
<div class="container" onclick="select(2)">
<img src="img/2.jpg">
</div>
<div class="container" onclick="select(3)">
<img src="img/3.jpg">
</div>
<div class="container" onclick="select(4)">
<img src="img/4.jpg">
</div>
</div>
</section>
<section id="description">
<div class="info" id="desc1">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div class="info" id="desc2">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div class="info" id="desc3">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div class="info" id="desc4">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
</section>
The javascript im using:
<script>
function hideunhide() {
var obj = document.getElementById("description");
if(obj.style.display == "block")
obj.style.display = "none";
else
obj.style.display = "block";
};
function select()
var obj = document.getElementByID(select())
</script>
I know that im messed up over the select(), but cant figure it out. Any help please? I can use html, css and javascript. Thanks
Edit: Added CSS
div.container {
display: inline-block;
margin: 25px;
border: solid 5px #333333;
border-radius: 5px;
}
div.container:hover {
border: solid 5px #fff;
}
.info {
border: solid 5px #333333;
text-align: center
}
Second version, based on comments, the text flows across the page width, responsive, meaning a text is always direct under its image even when image break line (using media query and a minimal script)
Note: working on a CSS only version, though not quite satisfied yet (fiddle demo)
(function(lastimg) {
document.querySelector("#img-select").addEventListener('click', function(e){
if (e.target.tagName.toLowerCase() == 'input') {
if (lastimg == e.target) {
e.target.checked = false;
lastimg = null;
} else {
lastimg = e.target;
}
}
});
}());
.container {
display: flex;
flex-wrap: wrap;
}
.container > label {
flex: 1;
flex-basis: 25%;
order: 1;
background-color: #eee;
}
.container > div {
flex: 1;
flex-basis: 100%;
order: 5;
background-color: #eee;
}
.container label img {
display: block;
margin: 0 auto;
}
.container input, .container input ~ div {
display: none;
}
.container input:checked ~ div {
display: block;
padding: 10px;
}
.container div div {
text-align: center;
}
#media screen and (max-width: 650px) {
.container > label {
flex-basis: 50%;
}
.container > label:nth-of-type(3),
.container > label:nth-of-type(4) {
order: 3;
}
.container > div:nth-of-type(1),
.container > div:nth-of-type(2) {
order: 2;
}
}
#media screen and (max-width: 325px) {
.container > label {
flex-basis: 50%;
}
.container > label:nth-of-type(1),
.container > div:nth-of-type(1) {
order: 1;
}
.container > label:nth-of-type(2),
.container > div:nth-of-type(2) {
order: 2;
}
.container > label:nth-of-type(3),
.container > div:nth-of-type(3) {
order: 3;
}
.container > label:nth-of-type(4),
.container > div:nth-of-type(4) {
order: 4;
}
}
<div id="img-select" class="container">
<label for="img1">
<img src="http://placehold.it/150x200" alt="">
</label>
<label for="img2">
<img src="http://placehold.it/150x200" alt="">
</label>
<label for="img3">
<img src="http://placehold.it/150x200" alt="">
</label>
<label for="img4">
<img src="http://placehold.it/150x200" alt="">
</label>
<div>
<input id="img1" type="radio" name="img-descr">
<div>Some text for img 1 that flow across full page width</div>
</div>
<div>
<input id="img2" type="radio" name="img-descr">
<div>Some text for img 2</div>
</div>
<div>
<input id="img3" type="radio" name="img-descr">
<div>Some text for img 3</div>
</div>
<div>
<input id="img4" type="radio" name="img-descr">
<div>Some text for img 4</div>
</div>
</div>
In this, the first version, the text is positioned under its image all the time, and will be responsive as well on smaller screens. (this version is still use a minimal script)
(function(lastimg) {
document.querySelector("#img-select").addEventListener('click', function(e){
if (e.target.tagName.toLowerCase() == 'input') {
if (lastimg == e.target) {
e.target.checked = false;
lastimg = null;
} else {
lastimg = e.target;
}
}
});
}());
label {
display: inline-block;
vertical-align: top;
}
label img {
display: block;
}
label input, label span {
display: none;
}
label input:checked ~ span {
display: inline;
}
<div id="img-select">
<label>
<input type="radio" name="img-descr">
<img src="http://placehold.it/150x200" alt="">
<span>Some text for img 1</span>
</label>
<label>
<input type="radio" name="img-descr">
<img src="http://placehold.it/150x200" alt="">
<span>Some text for img 2</span>
</label>
<label>
<input type="radio" name="img-descr">
<img src="http://placehold.it/150x200" alt="">
<span>Some text for img 3</span>
</label>
<label>
<input type="radio" name="img-descr">
<img src="http://placehold.it/150x200" alt="">
<span>Some text for img 4</span>
</label>
</div>
PLease try this, hope it might help buddy! its working basic on my console, you can enhance it more:
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<section class="img" style="text-align:center;">
<div class="container" onclick="hideunhide(1)">
<img src="img/1.jpg">
</div>
<div class="container" onclick="hideunhide(2)">
<img src="img/2.jpg">
</div>
<div class="container" onclick="hideunhide(3)">
<img src="img/3.jpg">
</div>
<div class="container" onclick="hideunhide(4)">
<img src="img/4.jpg">
</div>
</section>
<section id="description">
<div id="1" style="display:none;">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div id="2" style="display:none;">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div id="3" style="display:none;">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
<div id="4" style="display:none;">
<h1>people</h1>
<p>time</p>
<p>country</p>
</div>
</section>
<script>
function hideunhide(id) {
var obj = document.getElementById(id);
if(obj.style.display == "block")
obj.style.display = "none";
else
obj.style.display = "block";
};
</script>
</body>
</html>