I tried to create a gallery, if you click on the picture, then a new model box is shown, in this window there is next and back button but it doesn't work
console.log("jdkf");
var expandImg = document.getElementById("expandedImg");
let img = document.getElementsByClassName("pic");
let contener = document.getElementById("container");
for (let i = 0; i < img.length; i++) {
img[i].addEventListener("click", (event) => {
let cur = event.target;
contener.style.display = "block"
expandImg.src = cur.src;
})
}
function next() {
img[i].nextSibling
}
function back() {
img[i].previousSibling
}
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#content {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
.pic.active {
opacity: 0.5;
}
.pic-large {
cursor: pointer;
}
#expandedImg {
width: 700px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s;
}
/* The expanding image container */
.container {
display: none;
/* Hidden by default عكسها block */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
padding-top: 100px;
/* Location of the box */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(252, 252, 252);
/* Fallback color */
background-color: rgba(255, 255, 255, 0.8);
/* Black w/ opacity */
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: #000;
font-size: 35px;
cursor: pointer;
}
#btn {
position: absolute;
top: 80%;
left: 50%;
z-index: 2;
}
<div class="container" id="container">
<div id="btn">
<input type="button" value="Next" onclick="next()" id="next">
<input type="button" value="previous" onclick="back()" id="back">
</div>
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg">
<div id="imgtext"></div>
</div>
<div id="content">
<img class="pic active" src="https://picsum.photos/id/200/200/200" alt="">
<img class="pic" src="https://picsum.photos/id/400/200/200" alt="">
<img class="pic" src="https://picsum.photos/id/201/200/200" alt="">
<img class="pic" src="https://picsum.photos/id/450/200/200" alt="">
</div>
I think you want something like this
There are some issues with the images not loading fast from the server, but the code should work
const expandImg = document.getElementById("expandedImg");
const imgs = document.querySelectorAll(".pic");
const imgText = document.getElementById("imgtext");
const container = document.getElementById("container");
let cur = 0;
container.addEventListener("click", (event) => {
const tgt = event.target;
if (tgt.classList.contains("closebtn")) {
container.classList.add("hide")
return;
}
const dir = tgt.id === "next" ? 1 : -1;
cur += dir;
if (cur < 0) cur = 0;
if (cur >= imgs.length) cur = imgs.length - 1;
expandImg.src = imgs[cur].src;
imgText.textContent = imgs[cur].alt;
})
document.getElementById("content").addEventListener("click", (event) => {
cur = event.target.dataset.idx
container.classList.remove("hide")
})
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#content {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
.pic.active {
opacity: 0.5;
}
.pic-large {
cursor: pointer;
}
#expandedImg {
width: 700px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s;
}
/* The expanding image container */
.container {
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
padding-top: 100px;
/* Location of the box */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(252, 252, 252);
/* Fallback color */
background-color: rgba(255, 255, 255, 0.8);
/* Black w/ opacity */
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: #000;
font-size: 35px;
cursor: pointer;
}
#btn {
position: absolute;
top: 80%;
left: 50%;
z-index: 2;
}
.hide {
display: none;
}
<div class="container hide" id="container">
<div id="btn">
<input type="button" value="Previous" id="prev">
<input type="button" value="Next" id="next">
</div>
<span class="closebtn">×</span>
<img id="expandedImg" src="">
<div id="imgtext"></div>
</div>
<div id="content">
<img class="pic active" data-idx="0" src="https://picsum.photos/id/200/200/200" alt="Picture 1">
<img class="pic" data-idx="1" src="https://picsum.photos/id/400/200/200" alt="Picture 2">
<img class="pic" data-idx="2" src="https://picsum.photos/id/201/200/200" alt="Picture 3">
<img class="pic" data-idx="3" src="https://picsum.photos/id/450/200/200" alt="Picture 4">
</div>
Related
Im not really sure why the span tag is not closing
Does it have to do with my selection being a div in js?
Please let me know what I can change in order to make this work.
Ive tried to switch out the labels of the classes and tested selectors as well
Here is my code.
document.querySelectorAll('.imageContainer div').forEach(image => {
image.onclick = () => {
document.querySelector('.popup-image').style.display = 'block';
document.querySelector('.popup-image img').div = image.getAttribute('data-img');
}
});
document.querySelector('.popup-image span').onclick = () => {
document.querySelector('.popup-image').style.display = 'none';
};
/* modal */
.container .popup-image {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.641);
height: 100%;
width: 100%;
z-index: 100;
display: none;
}
.container .popup-image span {
position: absolute;
top: 0;
right: 10px;
font-size: bolder;
color: #fff;
cursor: pointer;
z-index: 100;
}
.container .popup-image img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 5px solid #fff;
width: 750px;
object-fit: cover;
}
#media only screen and (max-width: 600px) {
.container .popup-image img {
width: 99%;
}
}
<div class="imageContainer">
<div class="entry work-entry branding">
<div class="entry-image image imageBG" data-img="./src/assets/img/feature1.jpeg">
</div>
<div class="work-entry-hover">
<div class="work-entry-content">
<div class="work-entry-title">Brand</div>
<div class="work-entry-cat">Los Angeles, CA</div>
</div>
</div>
</div>
<!-- modal -->
<div class="popup-image">
<img src="./src/assets/img/feature1.jpeg" alt="">
<span>×</span>
</div>
</div>
Since the 'x' button is inside the other element, the function to set display: block is being called when you click on the span, which is overriding the display: none; that you're setting. You can stop this by running e.stopPropagation(); in the event handler, which will prevent the click event from triggering on any parent elements.
document.querySelectorAll('.imageContainer div').forEach(image => {
image.onclick = () => {
document.querySelector('.popup-image').style.display = 'block';
document.querySelector('.popup-image img').div = image.getAttribute('data-img');
}
});
document.querySelector('.popup-image span').onclick = (e) => {
e.stopPropagation();
document.querySelector('.popup-image').style.display = 'none';
};
/* modal */
.container .popup-image {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.641);
height: 100%;
width: 100%;
z-index: 100;
display: none;
}
.container .popup-image span {
position: absolute;
top: 0;
right: 10px;
font-size: bolder;
color: #fff;
cursor: pointer;
z-index: 100;
}
.container .popup-image img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 5px solid #fff;
width: 750px;
object-fit: cover;
}
#media only screen and (max-width: 600px) {
.container .popup-image img {
width: 99%;
}
}
<div class="imageContainer">
<div class="entry work-entry branding">
<div class="entry-image image imageBG" data-img="./src/assets/img/feature1.jpeg">
</div>
<div class="work-entry-hover">
<div class="work-entry-content">
<div class="work-entry-title">Brand</div>
<div class="work-entry-cat">Los Angeles, CA</div>
</div>
</div>
</div>
<!-- modal -->
<div class="popup-image">
<img src="./src/assets/img/feature1.jpeg" alt="">
<span>×</span>
</div>
</div>
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
Why the timeline is run only once after pressing the arrow? I would like it to be executed every time you click right arrow.
I tried different timeline layouts in the code but it didn't help.
the arrangement of the subtitles on the computer looks better
Link Codepen https://codepen.io/jarek-babiak/pen/GRQLBgy
const slid = [...document.querySelectorAll('.slid')];
const arrows = document.querySelectorAll('.arrows-slider .arrow');
slid.forEach(s => {
if (s.classList.contains('active') == false) {
// s.style.opacity = '0';
}
});
const slider = grow => {
for (i = 0; i < slid.length; i++) {
const s = slid[i];
if (s.classList.contains('active')) {
let numberArray = slid.indexOf(s);
numberArray += grow;
// if(numberArray > slid.length-1) numberArray = 0;
if (numberArray > slid.length - 1 || numberArray < 0) {
break;
} else {
s.classList.remove('active');
slid[numberArray].classList.add('active');
break;
};
}
}
}
const sliderMove = gsap.timeline({
paused: true
});
slid.forEach(s => {
sliderMove
.to(s, {
duration: .1,
x: "-100%"
});
});
arrows.forEach(arrow => {
arrow.addEventListener('click', function() {
if (this.classList.contains('arrows-right')) {
const grow = 1;
slider(grow);
sliderMove.play();
} else if (this.classList.contains('arrows-left')) {
const grow = -1;
slider(grow);
}
});
});
body {
/* overflow: hidden; */
}
.slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-image: url('../img/mirrored_squares.png');
height: 100vh;
display: flex;
}
.slid {
position: relative;
width: 100%;
height: 100vh;
/* opacity: 0; */
flex-shrink: 0;
transition: .3s;
}
.active {
/* opacity: 1 !important; */
}
.img-slid {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 35%;
height: 50%;
background-size: cover;
}
.engine {
background-color: gray;
}
.exhaust {
background-color: pink;
}
.car {
background-color: red;
}
.slid-text {
position: absolute;
top: 50%;
left: 11%;
transform: translateY(-50%);
font-size: 8rem;
text-transform: uppercase;
color: #fff;
font-family: 'Black Ops One', cursive;
}
.number-slaid {
position: absolute;
bottom: 8%;
right: 8%;
font-size: 2rem;
color: #fff;
font-family: 'Black Ops One', cursive;
}
/* .arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%);
}
.line-arrow {
width: 2px;
height: 70px;
background-color: black;
}
.top-line {
transform: rotate(48deg) translateY(25%);
}
.bottom-line {
transform: rotate(-48deg) translateY(-25%);
} */
.arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%) rotate(45deg);
}
.arrows-right {
position: absolute;
top: 50%;
right: 5%;
transform: translateY(-50%) rotate(-135deg);
}
.arrow {
width: 80px;
height: 80px;
border-left: 2px solid #000;
border-bottom: 2px solid #000;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<main>
<section class="slider">
<div class="slid slid1 active">
<div class="engine img-slid"> </div>
<p class="slid-text">Silniki</p>
<p class="number-slaid">01</p>
</div>
<div class="slid slid2 ">
<div class="exhaust img-slid"></div>
<p class="slid-text">Wydechy</p>
<p class="number-slaid">02</p>
</div>
<div class="slid slid3 ">
<div class="car img-slid"></div>
<p class="slid-text">Samochody</p>
<p class="number-slaid">03</p>
</div>
<div class="arrows-slider">
<div class="arrows-left arrow"></div>
<div class="arrows-right arrow"></div>
</div>
</section>
</main>
I am trying to make an image carousel which can slide on it's own but it can also be controlled by arrow buttons. I've added keyframes which will control the sliding animation of the slider but for the buttons, I don't know where to begin. Is there any way to add this function to the buttons using javascript?
.carousel {
overflow: hidden;
}
.carousel figure {
position: relative;
width: 600vw;
animation: 35s slider infinite;
display: table;
margin-block-start: 0;
margin-block-end: 0;
margin-inline-start: 0;
margin-inline-end: 0;
}
.carousel figure img {
width: 100vw;
}
#keyframes slider {
0% {
left: 0vw;
}
14% {
left: 0vw;
}
15% {
left: -100vw;
}
29% {
left: -100vw;
}
30% {
left: -200vw;
}
44% {
left: -200vw;
}
45% {
left: -300vw;
}
59% {
left: -300vw;
}
60% {
left: -400vw;
}
74% {
left: -400vw;
}
75% {
left: -500vw;
}
90% {
left: -500vw;
}
100% {
left: 0vw;
}
}
.main_carousel_right_arrow {
font-size: 2vw;
padding: 5vw 2vw;
background-color: rgb(255, 255, 255);
top: 6%;
position: absolute;
right: 0px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.main_carousel_left_arrow {
font-size: 2vw;
padding: 5vw 2vw;
background-color: rgb(255, 255, 255);
top: 6%;
position: absolute;
left: 0px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="carousel">
<figure>
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/a341a61df77a5715.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/971922653b729a9e.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/4075d3bac7ced1e9.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/411e38f49c1486b4.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/8c30d1a38636e9fa.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/ce435d49852d2b8c.jpg?q=50">
</figure>
<div>
<span class="main_carousel_left_arrow"><i class="fas fa-arrow-left"></i></span>
<span class="main_carousel_right_arrow"><i class="fas fa-arrow-right"></i></span>
</div>
</div>
The problem with your slider was that the full animation cycle = 1 iteration, which means that the back and forward buttons cannot be used with this slider, as you have by default. I deleted your #keyframes algorithm, replacing it with a setInterval().
The slider is entirely written in javascript.
Also add transition: 1s to .carousel figure for smooth slide transitions.
In the previous task, I recommended that you use the display: table in the selector .carousel figure. Now you need to replace it with a display: flex.
let anime = document.querySelector('.carousel figure');
let left = document.querySelector('.main_carousel_left_arrow');
let right = document.querySelector('.main_carousel_right_arrow');
var step = 0;
function animate() {
if (step > -600) {
anime.style.transform = 'translateX('+ step +'vw)';
} else {
anime.style.transform = 'transformX(100vw)';
step = 100;
}
}
setInterval(function () {
step = step - 100;
animate();
}, 7000);
right.onclick = function() {
step = step - 100;
animate();
}
left.onclick = function() {
step = step + 100;
animate();
}
.carousel {
overflow: hidden;
}
.carousel figure {
position: relative;
width: 600vw;
transition: 1s;
display: flex;
margin: 0;
}
.carousel figure img {
width: 100vw;
}
.main_carousel_right_arrow {
font-size: 2vw;
padding: 5vw 2vw;
background-color: rgb(255, 255, 255);
top: 6%;
position: absolute;
right: 0px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.main_carousel_left_arrow {
font-size: 2vw;
padding: 5vw 2vw;
background-color: rgb(255, 255, 255);
top: 6%;
position: absolute;
left: 0px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="carousel">
<figure>
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/a341a61df77a5715.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/971922653b729a9e.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/4075d3bac7ced1e9.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/411e38f49c1486b4.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/8c30d1a38636e9fa.jpg?q=50">
<img src="https://rukminim1.flixcart.com/flap/1688/280/image/ce435d49852d2b8c.jpg?q=50">
</figure>
<div>
<span class="main_carousel_left_arrow"><i class="fas fa-arrow-left"></i></span>
<span class="main_carousel_right_arrow"><i class="fas fa-arrow-right"></i></span>
</div>
</div>
I have developed a lightbox feature which I am trying to figure out how to close the lightbox preview window by clicking on the background area behind the image displayed, (while keeping the image unaffected).
Here's a demo snippet. There's a button toggle control at the upper, right-hand corner to close the lightbox window, but I would like to be able to close the window by clicking on the background area surrounding the image as well. Any input?
UPDATE: The Solution
Finally got this working, thanks to Marouen Mhiri. Updated my original snippet here:
var $scrollTop = 0;
$('.pic > img').click(function() {
var $body = $('body');
$scrollTop = $(window).scrollTop();
$body.css('position', 'fixed');
$body.css('top', '-' + $scrollTop + 'px');
$body.css('background-position', '0 -' + $scrollTop + 'px');
var srcToCopy = $(this).attr('src');
$body.find('.imgsrc').attr('src', srcToCopy);
$body.addClass('no-scroll');
$('#view').addClass("target");
});
$('#customlightbox-controls').on('click', function() {
var $body = $('body');
$body.css('position', '');
$body.css('background-position', '');
$scrollTop = $(window).scrollTop($scrollTop);
$body.removeClass('no-scroll');
$('#view').removeClass("target");
});
$('.customlightbox-imgwrap').on('click', function(e) {
if(!$(e.target).hasClass('imgsrc')){
var $body = $('body');
$body.css('position', '');
$body.css('background-position', '');
$scrollTop = $(window).scrollTop($scrollTop);
$body.removeClass('no-scroll');
$('#view').removeClass("target");
}
});
body {
background-color: #58d68d;
margin: 0;
padding: 0;
border: 0;
height: 100%;
width: 100%;
}
body.no-scroll {
overflow: hidden;
height: auto;
width: 100%;
}
.pic,
#imgsrc {
display: inline-block;
cursor: pointer;
}
img {
width: 150px
}
a {
display: inline-block;
line-height: 0;
}
.container {
text-align: center;
display: block;
width: 100%;
line-height: 0;
}
.customlightbox {
top: 0%;
bottom: 0%;
box-sizing: border-box;
position: fixed;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
z-index: -5;
opacity: 0;
}
.customlightbox-imgwrap {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
position: relative;
text-align: center;
}
.customlightbox img {
width: auto;
margin: auto;
max-width: 100%;
max-height: 100%;
opacity: 0;
position: relative;
top: 50%;
transform: translateY(-50%);
}
#customlightbox-controls {
cursor: pointer;
box-sizing: border-box;
position: fixed;
height: 50px;
width: 50px;
top: -50px;
right: -3px;
z-index: 5;
border-left: 2px solid white;
border-bottom: 2px solid white;
opacity: .7;
}
#close-customlightbox {
display: block;
position: absolute;
overflow: hidden;
height: 30px;
width: 30px;
right: 10px;
top: 10px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
#close-customlightbox:before {
content: "";
display: block;
position: absolute;
height: 0px;
width: 2px;
left: 14px;
top: 0;
background: white;
border-radius: 2px;
}
#close-customlightbox:after {
content: "";
display: block;
position: absolute;
width: 0px;
height: 2px;
top: 14px;
left: 0;
background: white;
border-radius: 2px;
}
.customlightbox.target {
z-index: 4;
opacity: 1;
display: inline-block;
}
.customlightbox.target img {
opacity: 1;
}
.customlightbox.target~#customlightbox-controls {
top: -3px;
}
.customlightbox.target~#customlightbox-controls #close-customlightbox:after {
width: 30px;
}
.customlightbox.target~#customlightbox-controls #close-customlightbox:before {
height: 30px;
}
.lb-animate {
-webkit-transition: 0.5s ease-in-out;
-moz-transition: 0.5s ease-in-out;
-ms-transition: 0.5s ease-in-out;
-o-transition: 0.5s ease-in-out;
transition: 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Lightbox Instance 1 -->
<div class="container">
<div class="pic">
<img src="https://syedimranrocks.files.wordpress.com/2012/09/flower01low1.png">
</div>
</div>
<!-- Lightbox Instance 2 -->
<div class="container">
<div class="pic">
<img src="http://downloadicons.net/sites/default/files/Rose-Coral-Icon-906534.png">
</div>
</div>
<!-- Lightbox Instance 3 -->
<div class="container">
<div class="pic">
<img src="https://images.vexels.com/media/users/3/136645/isolated/lists/54b1517db1906889a6971939de45d2a8-purple-sunflower-cartoon.png">
</div>
</div>
<!-- Lightbox Instance 4 -->
<div class="container">
<div class="pic">
<img src="http://i2.wp.com/lfisdelhi.com/wp-content/uploads/2016/05/Sunflower-icon.png">
</div>
</div>
<!-- Lightbox Instance 5 -->
<div class="container">
<div class="pic">
<img src="http://icongal.com/gallery/image/203372/birthday_flower_love_valentine_yellow_rose.png">
</div>
</div>
<!-- Lightbox Controls -->
<div class="customlightbox lb-animate" id="view">
<div class="customlightbox-imgwrap">
<img class="imgsrc" id="customlightbox-img" src="">
</div>
</div>
<div id="customlightbox-controls" class="lb-animate">
<a id="close-customlightbox" class="lb-animate"></a>
</div>
This question stems from a previous question, answered here.
just use the click event of the div containing the lightbox and fire the event only if the clicked area doesn't contain the image:
$('.customlightbox-imgwrap').on('click', function(e) {
if(!$(e.target).hasClass('imgsrc')){ // check if target is not the image displayed
var $body = $('body');
$body.css('position', '');
$body.css('background-position', '');
$scrollTop = $(window).scrollTop($scrollTop);
$body.removeClass('no-scroll');
$('#view').removeClass("target");
}
});
Hiding the lightbox by clicking on the background
It is possible by adding #view to the following code.
Before
$('#customlightbox-controls').on('click', function()
After
$('#customlightbox-controls, #view').on('click', function()
var $scrollTop = 0;
$('.pic > img').click(function() {
var $body = $('body');
$scrollTop = $(window).scrollTop();
$body.css('position', 'fixed');
$body.css('top', '-' + $scrollTop + 'px');
$body.css('background-position', '0 -' + $scrollTop + 'px');
var srcToCopy = $(this).attr('src');
$body.find('.imgsrc').attr('src', srcToCopy);
$body.addClass('no-scroll');
$('#view').addClass("target");
});
$('#customlightbox-controls, #view').on('click', function() {
var $body = $('body');
$body.css('position', '');
$body.css('background-position', '');
$scrollTop = $(window).scrollTop($scrollTop);
$body.removeClass('no-scroll');
$('#view').removeClass("target");
});
body {
background-color: #58d68d;
margin: 0;
padding: 0;
border: 0;
height: 100%;
width: 100%;
}
body.no-scroll {
overflow: hidden;
height: auto;
width: 100%;
}
.pic,
#imgsrc {
display: inline-block;
cursor: pointer;
}
img {
width: 150px
}
a {
display: inline-block;
line-height: 0;
}
.container {
text-align: center;
display: block;
width: 100%;
line-height: 0;
}
.customlightbox {
top: 0%;
bottom: 0%;
box-sizing: border-box;
position: fixed;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
z-index: -5;
opacity: 0;
}
.customlightbox-imgwrap {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
position: relative;
text-align: center;
}
.customlightbox img {
width: auto;
margin: auto;
max-width: 100%;
max-height: 100%;
opacity: 0;
position: relative;
top: 50%;
transform: translateY(-50%);
}
#customlightbox-controls {
cursor: pointer;
box-sizing: border-box;
position: fixed;
height: 50px;
width: 50px;
top: -50px;
right: -3px;
z-index: 5;
border-left: 2px solid white;
border-bottom: 2px solid white;
opacity: .7;
}
#close-customlightbox {
display: block;
position: absolute;
overflow: hidden;
height: 30px;
width: 30px;
right: 10px;
top: 10px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
#close-customlightbox:before {
content: "";
display: block;
position: absolute;
height: 0px;
width: 2px;
left: 14px;
top: 0;
background: white;
border-radius: 2px;
}
#close-customlightbox:after {
content: "";
display: block;
position: absolute;
width: 0px;
height: 2px;
top: 14px;
left: 0;
background: white;
border-radius: 2px;
}
.customlightbox.target {
z-index: 4;
opacity: 1;
display: inline-block;
}
.customlightbox.target img {
opacity: 1;
}
.customlightbox.target~#customlightbox-controls {
top: -3px;
}
.customlightbox.target~#customlightbox-controls #close-customlightbox:after {
width: 30px;
}
.customlightbox.target~#customlightbox-controls #close-customlightbox:before {
height: 30px;
}
.lb-animate {
-webkit-transition: 0.5s ease-in-out;
-moz-transition: 0.5s ease-in-out;
-ms-transition: 0.5s ease-in-out;
-o-transition: 0.5s ease-in-out;
transition: 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Lightbox Instance 1 -->
<div class="container">
<div class="pic">
<img src="https://syedimranrocks.files.wordpress.com/2012/09/flower01low1.png">
</div>
</div>
<!-- Lightbox Instance 2 -->
<div class="container">
<div class="pic">
<img src="http://downloadicons.net/sites/default/files/Rose-Coral-Icon-906534.png">
</div>
</div>
<!-- Lightbox Instance 3 -->
<div class="container">
<div class="pic">
<img src="https://images.vexels.com/media/users/3/136645/isolated/lists/54b1517db1906889a6971939de45d2a8-purple-sunflower-cartoon.png">
</div>
</div>
<!-- Lightbox Instance 4 -->
<div class="container">
<div class="pic">
<img src="http://i2.wp.com/lfisdelhi.com/wp-content/uploads/2016/05/Sunflower-icon.png">
</div>
</div>
<!-- Lightbox Instance 5 -->
<div class="container">
<div class="pic">
<img src="http://icongal.com/gallery/image/203372/birthday_flower_love_valentine_yellow_rose.png">
</div>
</div>
<!-- Lightbox Controls -->
<div class="customlightbox lb-animate" id="view">
<div class="customlightbox-imgwrap">
<img class="imgsrc" id="customlightbox-img" src="">
</div>
</div>
<div id="customlightbox-controls" class="lb-animate">
<a id="close-customlightbox" class="lb-animate"></a>
</div>