I created a gallery using the following codepen and now I'm trying to add the function click to expand an image, using this JS method. Sadly I cannot get it to work.
Any advice would be very helpful, either regarding this expand option or an alternative. Mind you I'm completely new to JS.
Thanks in advance!
var modal = document.getElementById('myModal');
var img = document.getElementById('myImg');
var modalImg = document.getElementById("image");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
/*main div*/
.ponudba {
background-color: rgb(0, 0, 0);
z-index: 3;
}
.image-grid {
padding: 12px;
}
.image-row {
display: flex;
}
.image-row .image {
margin: 12px;
height: 220px;
}
.image {
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
border-radius: 3px;
transition-duration: 0.5s;
filter: contrast(75%);
transition: all 0.3s ease-in;
box-shadow: 0 3px 4px rgba(0, 0, 0, 0.3),
0 3px 4px rgba(0, 0, 0, 0.15),
0 3px 4px rgba(0, 0, 0, 0.7);
margin: 0 0 0 15%;
display: block;
height: 100vh;
max-width: 100%;
animation-name: zoom;
animation-duration: 0.6s;
z-index: 3;
}
.image:hover {
filter: contrast(100%);
transition: all 0.3s ease-out;
cursor: pointer;
}
.image-01 {
background-image: url(images/...jpg);
flex: 2;
background-position: 50% 60%;
}
.image-02 {
background-image: url(images/...jpg);
flex: 1.2;
}
.image-03 {
background-image: url(images/...jpg);
flex: 1.5;
background-position: 50% 70%;
}
.image-04 {
background-image: url(images/...jpg);
flex: 3;
background-position: 50% 60%;
}
.image-05 {
background-image: url(images/...jpg);
flex: 3;
}
.image-06 {
background-image: url(images/...jpg);
flex: 2;
}
.image-07 {
background-image: url(images/...jpg);
flex: 1.5;
}
.image-08 {
background-image: url(images/...jpg);
flex: 2.5;
background-position: 50% 70%;
}
.image-09 {
background-image: url(images/...jpg);
flex: 1;
}
.image-10 {
background-image: url(images/...jpg);
flex: 3;
background-position: 50% 80%;
}
#myImg {
border-radius: 3px;
cursor: pointer;
transition: 0.3s;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.9);
}
#keyframes zoom {
from {transform: scale(0.1)}
to {transform: scale(1)}
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
#media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
.image-row {
flex-direction: column;
}
.image-row .image {
flex-basis: auto;
}
}
<div class="ponudba" id="ponudba">
<div class="image-grid">
<div class="image-row">
<div class="image image-01" id="image-01"></div>
<div class="image image-02" id="image-02"></div>
<div class="image image-03" id="image-03"></div>
<div class="image image-04" id="image-04"></div>
</div>
<div class="image-row">
<div class="image image-06" id="image-06"></div>
<div class="image image-05" id="image-05"></div>
<div class="image image-07" id="image-07"></div>
</div>
<div class="image-row">
<div class="image image-08" id="image-08"></div>
<div class="image image-09" id="image-09"></div>
<div class="image image-10" id="image-10"></div>
</div>
</div>
<div id="myModal" class="modal">
<span class="close">×</span>
<img class="modal-content" id="image">
</div>
</div>
id should be unique.
If you have multiple images, you can use getElementsByClassName to get all elements you need to expand.
Then use for loop to add onClick function to each element.
let imgs = document.getElementsByClassName("image"),
imgModal = document.getElementById('image'),
modal = document.getElementById('myModal');
for (let i = 0; i < imgs.length; i++) {
imgs[i].onclick = function (e) { imgZoom(e) }
}
function imgZoom(e) {
modal.style.display = 'block';
let src = e.target.style.backgroundImage.slice(4, -1).replace(/['"]/g, "")
imgModal.src = src
}
let span = document.getElementsByClassName('close')[0];
span.onclick = function () {
modal.style.display = 'none';
}
Because your image is background-img in css, use backgroundImage.slice(4, -1).replace(/['"]/g, "") to get url.
/-----Edit-----/
Sorry I made some mistakes in my code.
let imgs = document.getElementsByClassName("image-row") should be
let imgs = document.getElementsByClassName("image")
for (let i = 0; i < imgBlocks.length; i++) should be
for (let i = 0; i < imgs.length; i++)
modal is not defined
background-img: url('...'); should write in html file, or js can't get the url.
<div class="image image-01" id="image-01" style="background-image: url('22.png');"></div>
About your question
It's not necessary to add an id on every image (except modal) in this case.
I select images by class name image in:
<div class="image image-01" id="image-01"></div>
Do I need to add a for loop for every element?
You need to add onclick to every element you want to expand.
Due to I selected images by class name, the object will be something like this
Use for loop to add onclick for every <div class="image imag...</div>
style.backgroundImage = url('22.png')
.slice(4, -1).replace(/['"]/g, "") will create a string from url("22.png"), select "22.png", then replace ' or " if exist.
The final result will be 22.png.
So after asking a collegue for help, this is what I got - an image gallery with clickable images.
Here's the pen: https://codepen.io/fullstackgenerator/pen/YzaqYdb
var modal = document.getElementById('Modal');
var imgaes = document.getElementsByClassName('image');
var modalImg = document.getElementById("image-modal");
imgaes = [].slice.call(imgaes);
console.log(imgaes);
imgaes.forEach(function(item){
item.onclick = function(){
modal.style.display = "block";
modalImg.src = this.getAttribute('src');
}
})
var span = document.getElementsByClassName("close")[0];
modalImg.onclick = function() {
modal.style.display = "none";
}
body {
margin: 0;
background-color: rgb(0, 0, 0);
}
.ponudba {
position: relative;
background-color: rgb(0, 0, 0);
height: 100vh;
max-width: 100%;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
z-index: 6;
}
.image-grid {
padding: 12px;
}
.image-row {
display: flex;
}
.image-row .image {
margin: 12px;
height: 220px;
}
.image {
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
border-radius: 3px;
height: 95%;
max-width: 100%;
}
.image:hover {
transition: all 0.3s ease-out;
cursor: pointer;
}
.image-01 {
background-image: url(https://res.cloudinary.com/dtpgi0zck/image/upload/s--fMAvJ-9u--/c_fit,h_580,w_860/v1/EducationHub/photos/sun-blasts-a-m66-flare.jpg);
flex: 2;
background-position: 50% 60%;
}
.image-02 {
background-image: url(https://cdn.mos.cms.futurecdn.net/KqzWwkCMPeZHFra2hkiJWj.jpg);
flex: 1.2;
}
.image-03 {
background-image: url(https://acs-h.assetsadobe.com/is/image//content/dam/cen/99/11/WEB/09911-feature3-venus.jpg/?$responsive$&wid=700&qlt=90,0&resMode=sharp2);
flex: 1.5;
background-position: 50% 70%;
}
.image-04 {
background-image: url(https://cdn.mos.cms.futurecdn.net/yCPyoZDQBBcXikqxkeW2jJ-1200-80.jpg);
flex: 3;
background-position: 50% 60%;
}
.image-05 {
background-image: url(https://images.24ur.com/media/images/1000xX/Oct2020/51ae60002d9189cc75b0_62469955.jpg?v=6e93);
flex: 3;
}
.image-06 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg/801px-Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg);
flex: 2;
}
.image-07 {
background-image: url(https://images.24ur.com/media/images/884xX/Oct2019/d33eec2c51_62323281.jpg?v=d41d);
flex: 1.5;
}
.image-08 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png/800px-Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png);
flex: 2.5;
}
.image-09 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Neptune_Full.jpg/640px-Neptune_Full.jpg);
flex: 1;
}
.image-10 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Pluto_in_True_Color_-_High-Res.jpg/800px-Pluto_in_True_Color_-_High-Res.jpg);
flex: 3;
}
#myImg {
border-radius: 3px;
cursor: pointer;
transition: 0.3s;
}
.modal {
display: none;
position: fixed;
z-index: 10;
left: 0;
top: 0;
width: 100%;
height: 100vh;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.9);
}
.modal-content {
margin: auto;
display: block;
animation-name: zoom;
animation-duration: 0.6s;
}
#keyframes zoom {
from {transform: scale(0.1)}
to {transform: scale(1)}
}
#media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
.image-row {
flex-direction: column;
}
.image-row .image {
flex-basis: auto;
}
}
<!--a BIG thank you to #awecodeman!-->
<div class="ponudba" id="ponudba">
<div class="image-grid">
<div class="image-row">
<div class="image image-01" id="image-01" src="https://res.cloudinary.com/dtpgi0zck/image/upload/s--fMAvJ-9u--/c_fit,h_580,w_860/v1/EducationHub/photos/sun-blasts-a-m66-flare.jpg"></div>
<div class="image image-02" id="image-02" src="https://cdn.mos.cms.futurecdn.net/KqzWwkCMPeZHFra2hkiJWj.jpg"></div>
<div class="image image-03" id="image-03" src="https://acs-h.assetsadobe.com/is/image//content/dam/cen/99/11/WEB/09911-feature3-venus.jpg/?$responsive$&wid=700&qlt=90,0&resMode=sharp2"></div>
<div class="image image-04" id="image-04" src="https://cdn.mos.cms.futurecdn.net/yCPyoZDQBBcXikqxkeW2jJ-1200-80.jpg"></div>
</div>
<div class="image-row">
<div class="image image-05" id="image-05" src="https://images.24ur.com/media/images/1000xX/Oct2020/51ae60002d9189cc75b0_62469955.jpg?v=6e93"></div>
<div class="image image-06" id="image-06" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg/801px-Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg"></div>
<div class="image image-07" id="image-07" src="https://images.24ur.com/media/images/884xX/Oct2019/d33eec2c51_62323281.jpg?v=d41d"></div>
</div>
<div class="image-row"">
<div class="image image-08" id="image-08" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png/800px-Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png"></div>
<div class="image image-09" id="image-09" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Neptune_Full.jpg/640px-Neptune_Full.jpg"></div>
<div class="image image-10" id="image-10" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Pluto_in_True_Color_-_High-Res.jpg/800px-Pluto_in_True_Color_-_High-Res.jpg"></div>
<div id="Modal" class="modal">
<span class="close">×</span>
<img class="modal-content image" id="image-modal"></div>
</div>
</div>
Related
Kinda like this:
Design picture
I've gotten the code for the menu in the right format.
I've tried to get the code to make an animation to the right. Although, it doesn't work the way I want it to.
Here's the code I have written thus far:
HTML:
> <link rel="stylesheet" href="index.css"> <link rel="stylesheet"
> href="jason.js"> <div id="menu">
> <div id="menu-items">
> About
> Team
> Contact us
>
> </div>
> <div id="menu-background-pattern"></div>
> <div id="menu-background-image"></div> </div>
CSS:
body {
background-color: rgb(20, 20, 20);
margin: 0px; }
/* Menu items */
#menu {
height: 100vh;
display: flex;
align-items: center; }
.menu-item {
color: white;
font-size: clamp(3rem, 8vw, 8rem);
font-family: "Ibarra Real Nova", serif;
display: block;
text-decoration: none;
padding: clamp(0.25rem, 0.5vw, 1rem) 0rem;
transition: opacicity 400ms ease; }
#menu-items {
margin-left: clamp(4rem, 20vw, 48rem);
position: relative;
z-index: 2; }
#menu-items:hover > .menu-item {
opacity: 0.3; }
#menu-items:hover > .menu-item:hover {
opacity: 1; }
/* Background pattern */
#menu-items:hover ~ #menu-background-pattern {
background-size: 11vmin 11vmin;
opacity: 0.5; }
#menu[data-active-index="0"] > #menu-background-pattern {
background-position: 0% -25%; }
#menu[data-active-index="1"] > #menu-background-pattern {
background-position: 0% -50%; }
#menu[data-active-index="2"] > #menu-background-pattern {
background-position: 0% -75%; }
#menu[data-active-index="3"] > #menu-background-pattern {
background-position: 0% -100%; }
#menu[data-active-index="0"] > #menu-background-image {
background-position: 0% 45%; }
#menu[data-active-index="1"] > #menu-background-image {
background-position: 0% 50%; }
#menu[data-active-index="2"] > #menu-background-image {
background-position: 0% 55%; }
#menu[data-active-index="3"] > #menu-background-image {
background-position: 0% 60%; }
#menu-background-image {
height: 100%;
width: 100%;
background-image: url('logo.png');
position: absolute;
left: 0px;
top: 0px;
z-index: 0;
background-position: center 40%;
background-size: 110vmax;
opacity: 0.15;
transition: opacity 800ms ease,
background-size 800ms ease,
background-position 800ms ease; }
#menu-items:hover ~ #menu-background-image {
background-size: 100vmax;
opacity: 0.10; }
JS:
const menu = document.getElementById("menu")
Array.from(document.getElementsByClassName("menu-item"))
.forEach((items, index) => {
items.onmouseover = () => {
menu.dataset.activeIndex = index;
}
});
I've been unable to get the menu to slide to the side. And make room for the text to the right without it ruining the zooming in animation and background animation.
The idea is for it to keep being zoomed out the same way whilst showing the text.
Here is the solution how to create a drawer with a multi page system using vanilla HTML, CSS & JavaScript
1. First create a HTML file named index.html
<!DOCTYPE html>
<html>
<head>
<link href="main.css" rel="stylesheet">
</head>
<body>
<section id="root" class="page">
<input type="button" value="Menu" onclick="onMenu()">
</section>
<section id="about" class="page">
<h1>About</h1>
<input type="button" value="Menu" onclick="onMenu()">
</section>
<section id="team" class="page">
<h1>Team</h1>
<input type="button" value="Menu" onclick="onMenu()">
</section>
<section id="contact" class="page">
<h1>Contact us</h1>
<input type="button" value="Menu" onclick="onMenu()">
</section>
<div id="menu">
<div id="close">
<input type="button" value="×" id="close-btn">
</div>
Home
About
Team
Contact us
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
2. Second create a CSS file named main.css
body {
margin: 0 auto;
padding: 0;
}
#root {
z-index: 1;
}
.page {
display: grid;
justify-items: center;
align-content: center;
width: 100vw;
height: 100vh;
background-color: #FFFFFF;
position: absolute;
overflow-x: hidden;
overflow-y: scroll;
}
section:target {
opacity: 1;
z-index: 1;
}
#menu {
display: none;
justify-items: center;
align-content: flex-start;
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
z-index: 1;
width: 75vw;
height: 100vh;
background-color: #333333AA;
}
.menu-btn {
margin: 1em 0 1em 0;
text-decoration: none;
color: #FFFFFF;
}
#close {
display: flex;
justify-content: center;
align-items: center;
width: inherit;
height: 10vh;
}
#close::before {
content: "";
width: 70vw;
}
#close-btn {
border: 0;
width: 25vw;
height: 10vh;
font-size: 64px;
color: #FFF;
background-color: transparent;
}
#keyframes slideRight {
from {
width: 0;
opacity: 0;
}
to {
width: 70vw;
opacity: 1;
}
}
#keyframes slideLeft {
from {
width: 70vw;
opacity: 1;
}
to {
width: 0;
opacity: 0;
}
}
3. Finally create sa JS file named app.js
let menu = document.querySelector("#menu");
let close_btn = document.querySelector("#close-btn");
let onMenu = () => {
menu.style.display = "grid";
menu.style.animationName = "slideRight";
menu.style.animationDuration = "0.5s";
};
close_btn.addEventListener("click", () => {
menu.style.animationName = "slideLeft";
menu.style.animationDuration = "0.5s";
setTimeout(() => {
menu.style.display = "none";
}, 400);
});
I can't get this effect to work on multiple images. JavaScript is calling for the getElementById it seems to only work for a single image,
I've tried to change it to getElementByClassName (and also the HTML and CSS) but then the function stops working, how can I get this effect on multiple images/ divs?
window.onload = function() {
var modal = document.getElementById('myModal');
var img = document.getElementById('myImg');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function() {
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
};
var span = document.getElementsByClassName("modal")[0];
span.onclick = function() {
modal.style.display = "none";
};
};
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
#caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
}
#myImg:hover {
cursor: pointer;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0.1)
}
to {
transform: scale(1)
}
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: white;
font-size: 60px;
font-weight: bold;
;
}
.close:hover {
color: #FFD270;
text-decoration: none;
cursor: pointer;
}
#myImg {
opacity: 1;
display: inline-block;
width: 100%;
height: auto;
transition: .45s ease;
backface-visibility: hidden;
margin: 20px;
}
<div class="myndir-a4" data-title="">
<img id="myImg" src="..\01.jpg" alt="this works fine">
<div id="myModal" class="modal">
<span class="close">X</span>
<img id="img01" class="modal-content" src="..\01.jpg" alt="">
<div id="caption"></div>
</div>
</div>
<div class="myndir-a4" data-title="">
<img id="myImg" src="..\02.jpg" alt="nothing happens">
<div id="myModal" class="modal">
<span class="close">X</span>
<img id="img01" class="modal-content" src="..\02.jpg" alt="">
<div id="caption"></div>
</div>
</div>
The answer is delegation
Note
changed display: none to hidden on the tag and
changed most IDs to class or removed them since they are no longer needed due to relative addressing
It would even be possible to have just one modal
window.addEventListener("DOMContentLoaded", () => {
document.getElementById("container").addEventListener("click", e => {
const tgt = e.target;
if (!tgt.matches(".myImg") && !tgt.matches(".close")) return; // not the image or close
const parent = tgt.closest("div.myndir-a4");
const modal = parent.querySelector('.modal');
if (tgt.matches(".close")) {
modal.hidden = true;
return;
}
const modalImg = parent.querySelector("img.modal-content");
const captionText = parent.querySelector(".caption");
modal.hidden = false;
modalImg.src = tgt.src;
captionText.innerHTML = tgt.alt;
});
});
.modal {
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
.caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
}
.myImg:hover {
cursor: pointer;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0.1)
}
to {
transform: scale(1)
}
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: white;
font-size: 60px;
font-weight: bold;
;
}
.close:hover {
color: #FFD270;
text-decoration: none;
cursor: pointer;
}
.myImg {
opacity: 1;
display: inline-block;
width: 100%;
height: auto;
transition: .45s ease;
backface-visibility: hidden;
margin: 20px;
}
<div id="container">
<div class="myndir-a4" data-title="">
<img class="myImg" src="https://via.placeholder.com/728x90.png?text=image1" alt="this works fine">
<div class="modal" hidden>
<span class="close">X</span>
<img class="modal-content" src="" alt="">
<div class="caption"></div>
</div>
</div>
<div class="myndir-a4" data-title="">
<img class="myImg" src="https://via.placeholder.com/728x90.png?text=image2" alt="This ALSO works now">
<div class="modal" hidden>
<span class="close">X</span>
<img class="modal-content" src="" alt="">
<div class="caption"></div>
</div>
</div>
</div>
I get
Im not that good at coding but i try some ways to put a transition effect but didint work.
Can you guys help me ?I will appreciate it a lot..........................................................................................................................................................................................................................................................................................................
Java
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
// Clear all images
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = "none";
}
}
// Init slider
function startSlide() {
reset();
sliderImages[0].style.display = "block";
}
// Show prev
function slideLeft() {
reset();
sliderImages[current - 1].style.display = "block";
current--;
}
// Show next
function slideRight() {
reset();
sliderImages[current + 1].style.display = "block";
current++;
}
// Left arrow click
arrowLeft.addEventListener("click", function() {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
});
// Right arrow click
arrowRight.addEventListener("click", function() {
if (current === sliderImages.length - 1) {
current = -1;
}
slideRight();
});
startSlide();
css
body,
#slider,
.wrap,
.slide-content {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
overflow-x: hidden;
}
.wrap {
position: relative;
}
.slide {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
/* .slide-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
} */
.delimitare {
background-color: r#141313ed;
width: 100%;
height: 100%;
padding-left: 10%;
padding-right: 10%;
}
.content-interior {
background-color: #141313;
width: 100%;
height: 100%;
}
.slide-content span {
font-size: 5rem;
color: #fff;
}
.arrow {
cursor: pointer;
position: absolute;
top: 50%;
margin-top: -35px;
width: 0;
height: 0;
border-style: solid;
}
#arrow-left {
border-width: 30px 40px 30px 0;
border-color: transparent #fff transparent transparent;
left: 0;
margin-left: 30px;
}
#arrow-right {
border-width: 30px 0 30px 40px;
border-color: transparent transparent transparent #fff;
right: 0;
margin-right: 30px;
}
html
<div class="wrap">
<div id="arrow-left" class="arrow"></div>
<div id="slider">
<div class="slide slide1">
<div class="slide-content">
</div>
</div>
</div>
<div class="slide slide2">
<div class="slide-content">
<span>Image Two</span>
</div>
</div>
<div class="slide slide3">
<div class="slide-content">
<span>Image Three</span>
</div>
</div>
</div>
<div id="arrow-right" class="arrow"></div>
</div>
So far you're doing well!
There's a lot of different ways to accomplish a fading slide, but the CSS "transition" property is an easy way to do it.
The problem here, though, is that you cannot transition the "display" property. Going from "display: block" to "display: none" cannot be transitioned. It either displays or doesn't. On or off, like a boolean.
I have put together a working example by updating the code you provided. Instead of using display to switch between slides, I updated it to change the opacity instead. Opacity can be transitioned, so I added the CSS to handle that as well.
(I also had to set the slide position to absolute so the slides stacked on top of each other.)
Quick side note: when you initially shared your code, you labeled your JavaScript as "Java". Java and JavaScript are two different coding languages so be careful with that in the future.
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
// Clear all images
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.opacity = "0";
}
}
// Init slider
function startSlide() {
reset();
sliderImages[0].style.opacity = "1";
}
// Show prev
function slideLeft() {
reset();
sliderImages[current - 1].style.opacity = "1";
current--;
}
// Show next
function slideRight() {
reset();
sliderImages[current + 1].style.opacity = "1";
current++;
}
// Left arrow click
arrowLeft.addEventListener("click", function () {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
});
// Right arrow click
arrowRight.addEventListener("click", function () {
if (current === sliderImages.length - 1) {
current = -1;
}
slideRight();
});
startSlide();
body,
#slider,
.wrap,
.slide-content {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
overflow-x: hidden;
background-color: blue;
}
.wrap {
position: relative;
}
.slide {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 0.5s ease;
position: absolute;
left: 0;
right: 0;
margin: auto;
}
.slide-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.delimitare {
background-color: r#141313ed;
width: 100%;
height: 100%;
padding-left: 10%;
padding-right: 10%;
}
.content-interior {
background-color: #141313;
width: 100%;
height: 100%;
}
.slide-content span {
font-size: 5rem;
color: #fff;
}
.arrow {
cursor: pointer;
position: absolute;
top: 50%;
margin-top: -35px;
width: 0;
height: 0;
border-style: solid;
z-index: 2;
}
#arrow-left {
border-width: 30px 40px 30px 0;
border-color: transparent #fff transparent transparent;
left: 0;
margin-left: 30px;
}
#arrow-right {
border-width: 30px 0 30px 40px;
border-color: transparent transparent transparent #fff;
right: 0;
margin-right: 30px;
}
<div class="wrap">
<div id="arrow-left" class="arrow">
</div>
<div id="slider">
<div class="slide slide1">
<div class="slide-content">
<span>Image One</span>
</div>
</div>
<div class="slide slide2">
<div class="slide-content">
<span>Image Two</span>
</div>
</div>
<div class="slide slide3">
<div class="slide-content">
<span>Image Three</span>
</div>
</div>
</div>
<div id="arrow-right" class="arrow"></div>
</div>
I'm using JavaScript to copy all styles of the div#old and use it to the div#young dynamically. I have successful done it, but when I add the transition property, the div#young applies a transition to all styles that I'm copying which I don't want.
Here is my code:
let styles = getComputedStyle(old);
all_style = ['width', 'height', 'background', 'border-radius', 'transition']
for (var i = 0; i < all_style.length; i++) {
young.style.setProperty(`--${all_style[i]}`, styles.getPropertyValue(all_style[i]));
}
.container {
display: flex;
justify-content: space-around;
width: 60%;
}
#old {
width: 110px;
height: 110px;
background: red;
border-radius: 50%;
transition: 1s ease-in-out all;
}
#young {
width: var(--width);
height: var(--height);
background: var(--background);
border-radius: var(--border-radius);
transition: var(--transition);
}
<div class="container">
<div id="old"></div>
<div id="young"></div>
</div>
In summary I don't want the transition on border-radius of div#young and the reason why I'm adding transition is for my animation, so to remove it won't answer my question.
make 0 the transition you don't want to happen. The order is important, the all need to be the first one:
let styles = getComputedStyle(old);
all_style = ['width', 'height', 'background', 'border-radius', 'transition']
for (var i = 0; i < all_style.length; i++) {
young.style.setProperty(`--${all_style[i]}`, styles.getPropertyValue(all_style[i]));
}
.container {
display: flex;
justify-content: space-around;
width: 60%;
}
#old {
width: 110px;
height: 110px;
background: red;
border-radius: 50%;
transition: 1s ease-in-out all,border-radius 0s;
}
#young {
width: var(--width);
height: var(--height);
background: var(--background);
border-radius: var(--border-radius);
transition: var(--transition);
}
<div class="container">
<div id="old"></div>
<div id="young"></div>
</div>
If you don't want any you can update the display value after the styles copy.
let styles = getComputedStyle(old);
all_style = ['width', 'height', 'background', 'border-radius', 'transition']
for (var i = 0; i < all_style.length; i++) {
young.style.setProperty(`--${all_style[i]}`, styles.getPropertyValue(all_style[i]));
}
young.style.display="initial"
.container {
display: flex;
justify-content: space-around;
width: 60%;
}
#old {
width: 110px;
height: 110px;
background: red;
border-radius: 50%;
transition: 1s ease-in-out all;
}
#young {
width: var(--width);
height: var(--height);
background: var(--background,none);
border-radius: var(--border-radius);
transition: var(--transition);
display:none;
}
<div class="container">
<div id="old"></div>
<div id="young"></div>
</div>
Add the transition with very little delay.
let styles = getComputedStyle(old);
all_style = ['width', 'height', 'background', 'border-radius', 'transition']
for (var i = 0; i < all_style.length; i++) {
if (all_style[i] !== 'transition') {
young.style.setProperty(`--${all_style[i]}`, styles.getPropertyValue(all_style[i]));
} else {
setTimeout(() => {
young.style.setProperty(`--${all_style[i]}`, styles.getPropertyValue(all_style[i]));
}, 10); // 1 second / 100
}
}
.container {
display: flex;
justify-content: space-around;
width: 60%;
}
#old {
width: 110px;
height: 110px;
background: red;
border-radius: 50%;
transition: 1s ease-in-out all;
}
#young {
width: var(--width);
height: var(--height);
background: var(--background);
border-radius: var(--border-radius);
transition: var(--transition);
}
<div class="container">
<div id="old"></div>
<div id="young"></div>
</div>
In a gallery of images, it is possible to click on each image in order to enlarge it. The sources of the enlarged images are received from the background-image of the small ones. I want to create a previous and next button to these enlarged images.
I have done this previously for a set of images with separate divs. However, I have never done it with arrays. Here is my code.
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = Array.from(document.querySelectorAll('.img-container .img'));
imgArr.forEach(function(img) {
img.onclick = function() {
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
}
});
/* This is the part where I tried adding previous & next
functions, but it doesn't work and it makes the close
button not work either. */
/*
var prev = document.getElementsByClassName("prev");
var next = document.getElementsByClassName("next");
var index = 0;
imgArr[index] = modalImg.src;
next.addEventListener('click', nextImage);
function nextImage() {
for (i = 0; i < 10; i++) {
modalImg.src = imgArr[index + 1];
}
}
previous.addEventListener('click', previousImage);
function previousImage() {
for (i = 0; i < 10; i++) {
modalImg.src = imgArr[index - 1];
}
}
*/
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = Array.from(document.querySelectorAll('.img-container .img'));
var currentIndex = 0;
imgArr.forEach(function(img, i) {
img.onclick = function() {
currentIndex = i;
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
}
});
var prev = document.getElementsByClassName("prev")[0];
var next = document.getElementsByClassName("next")[0];
next.addEventListener('click', nextImage);
function nextImage() {
currentIndex = (currentIndex+1)%imgArr.length;
var backgroundImage = imgArr[currentIndex].style.backgroundImage.slice(4, -1).replace(/"/g, '');
modalImg.src = backgroundImage
}
prev.addEventListener('click', previousImage);
function previousImage() {
currentIndex = (currentIndex+imgArr.length-1)%imgArr.length;
var backgroundImage = imgArr[currentIndex].style.backgroundImage.slice(4, -1).replace(/"/g, '');
modalImg.src = backgroundImage
}
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>
You can keep track of the currently clicked image, later you can increment/decrement the value based on which you can select image from the NodeList:
Please Note: You do not need Array.from() to implement forEach() on NodeList returned by querySelectorAll():
Try the following way:
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = document.querySelectorAll('.img-container .img');
var curSrc;
imgArr.forEach(function(img, i) {
img.onclick = function() {
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
curSrc = i;
}
});
var prev = document.querySelector(".prev");
var next = document.querySelector(".next");
next.addEventListener('click', nextImage);
function nextImage() {;
if(curSrc < imgArr.length - 1){
curSrc++;
modalImg.src = imgArr[curSrc].style.backgroundImage.slice(4, -1).replace(/"/g, '');
}
}
prev.addEventListener('click', previousImage);
function previousImage() {
if(curSrc>0){
curSrc--;
modalImg.src = imgArr[curSrc].style.backgroundImage.slice(4, -1).replace(/"/g, '');
}
}
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>