I am trying to create a pure JavaScript slider which automatically scrolls as the page loads. The slider gets successfully triggered for the first time and here comes the issue. When this slider goes through setInterval() function for the second iteration, the list items gets undefined (ie: the value of 'i'). Also I want the slider to autoscroll. I need this to get done with the help of pure JavaScript. Here is my code,
JS:
function slider() {
var ul = document.getElementById("imageSlider");
var liItems = ul.getElementsByTagName("li");
var imageWidth = liItems[0].offsetWidth;
var imageNumber = liItems.length;
setInterval(function () {
for (var i = 0; i <= liItems.length; i++) {
liItems[i].style.right = liItems[i].style.right + imageWidth + 'px';
}
}, 2000);
}
CSS:
.slider-wrapper {
height: 115px;
width: 100%;
}
.slide-wrapper {
height: 95px;
width: 274px;
background-image: linear-gradient(#aaaaaa,#e2e2e2);
background-size: auto 200%;
background-position: 0 100%;
transition: background-position 0.5s ease-out;
-webkit-transition: background-position 0.5s ease-out;
-moz-transition: background-position 0.5s ease-out;
-o-transition: background-position 0.5s ease-out;
-ms-transition: background-position 0.5s ease-out;
display: inline-block;
vertical-align: middle;
margin: 10px;
}
.slide-wrapper:hover {
height: 95px;
width: 274px;
background-position: 0 0;
}
.slide {
display: inline-block;
position: relative;
}
ul {
margin: 0;
padding: 0;
width: 100%;
}
.image {
text-align: center;
height: 95px;
width: 274px;
line-height: 92px;
}
.image-style {
max-width: 150px;
width: auto;
max-height: 75px;
height: auto;
vertical-align: middle;
}
.left-arrow {
width: 75px;
height: 115px;
float: left;
position: relative;
font-family: 'Dosis', sans-serif;
font-size: 75px;
}
.right-arrow {
width: 75px;
height: 115px;
float: right;
position: relative;
font-family: 'Dosis', sans-serif;
font-size: 75px;
}
.image-slider-ul {
text-align: center;
display: block;
white-space: nowrap;
padding: 0;
}
.container-middle {
display: inline-block;
height: 115px;
overflow: hidden;
width: 1188px;
}
HTML:
<body onload="slider()">
<ul id="imageSlider" class="image-slider-ul">
<div class="slider-wrapper">
<div class="left-arrow"><</div>
<div class="container-middle">
<li class="slide"><div class="slide-wrapper"><div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/1-Number-PNG.png" class="image-style"></div></div></li>
<li class="slide"><div class="slide-wrapper"><div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/2-Number-PNG.png" class="image-style"></div></div></li>
<li class="slide"><div class="slide-wrapper"><div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/3-Number-PNG.png" class="image-style"></div></div></li>
<li class="slide"><div class="slide-wrapper"><div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/4-Number-PNG.png" class="image-style"></div></div></li>
<li class="slide"><div class="slide-wrapper"><div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/5-Number-PNG.png" class="image-style"></div></div></li>
</div>
<div class="right-arrow">></div>
</div>
</ul>
</body>
Please help me figure this out! Thankyou..
we could make it automatic left sliding when periodical change of img element src with help of setInterval().
code:
function slider() {
// var ul = document.getElementById("imageSlider");
// var liItems = ul.getElementsByTagName("li");
// var imageWidth = liItems[0].offsetWidth;
// var imageNumber = liItems.length;
setInterval(function() {
var souc = document.getElementsByClassName("image-style");
var firstSrc = souc[0].src
for (var i = 0; i < souc.length -1; i++) {
souc[i].src = souc[i+1].src;
}
souc[souc.length-1].src = firstSrc;
}, 2000);
}
.slider-wrapper {
height: 115px;
width: 100%;
}
.slide-wrapper {
height: 95px;
width: 274px;
background-image: linear-gradient(#aaaaaa,#e2e2e2);
background-size: auto 200%;
background-position: 0 100%;
transition: background-position 0.5s ease-out;
-webkit-transition: background-position 0.5s ease-out;
-moz-transition: background-position 0.5s ease-out;
-o-transition: background-position 0.5s ease-out;
-ms-transition: background-position 0.5s ease-out;
display: inline-block;
vertical-align: middle;
margin: 10px;
}
.slide-wrapper:hover {
height: 95px;
width: 274px;
background-position: 0 0;
}
.slide {
display: inline-block;
position: relative;
}
ul {
margin: 0;
padding: 0;
width: 100%;
}
.image {
text-align: center;
height: 95px;
width: 274px;
line-height: 92px;
}
.image-style {
max-width: 150px;
width: auto;
max-height: 75px;
height: auto;
vertical-align: middle;
}
.left-arrow {
width: 75px;
height: 115px;
float: left;
position: relative;
font-family: 'Dosis', sans-serif;
font-size: 75px;
}
.right-arrow {
width: 75px;
height: 115px;
float: right;
position: relative;
font-family: 'Dosis', sans-serif;
font-size: 75px;
}
.image-slider-ul {
text-align: center;
display: block;
white-space: nowrap;
padding: 0;
}
.container-middle {
display: inline-block;
height: 115px;
overflow: hidden;
width: 1188px;
}
<body onload="slider()">
<div>
<ul id="imageSlider" class="image-slider-ul">
<div class="slider-wrapper">
<div class="left-arrow"><</div>
<div class="container-middle">
<li class="slide">
<div class="slide-wrapper">
<div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/1-Number-PNG.png" class="image-style"></div>
</div>
</li>
<li class="slide">
<div class="slide-wrapper">
<div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/2-Number-PNG.png" class="image-style"></div>
</div>
</li>
<li class="slide">
<div class="slide-wrapper">
<div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/3-Number-PNG.png" class="image-style"></div>
</div>
</li>
<li class="slide">
<div class="slide-wrapper">
<div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/4-Number-PNG.png" class="image-style"></div>
</div>
</li>
<li class="slide">
<div class="slide-wrapper">
<div class="image"><img src="http://www.pngall.com/wp-content/uploads/2016/04/5-Number-PNG.png" class="image-style"></div>
</div>
</li>
</div>
<div class="right-arrow">></div>
</div>
</ul>
</div>
</body>
Note:
open snippet in full page, you can understand clearly.
l hope it helps to you.
I am guessing that your problem arises as the first iteration moves elements to right but then does not repeat themselves as there are no elements to the left.
You could try to create a function which will move back all elements to the original position at the elements.lenth loop iteration as you'll be showing the animation to the last element as well.
Related
window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
}
.active {
opacity: 1;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>
How can I get the FadeInLeft effect when changing content from .opacity=0 to .opacity=1 on the left side.
I tried to solve this problem with the given script, but it did not work for me.
P.S. See this layout in fullscreen.
Here is a very ruff first draft
Since you already have the .active class being added to your .subtitle class to change opacity, you can just tack on CSS Animation to those classes.
In my example I have .subtitle > div set to right: 100%; and .active > div set to right: 0%; with a transition: 300ms;
Which will animate the block from the left side of the screen over to the right side in 300ms. You can play around with this until you get the animation where you'd like.
Here's a great article from MDN with more information about Using CSS Transitions
CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time. For example, if you change the color of an element from white to black, usually the change is instantaneous. With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.
Examples
div {
transition: <property> <duration> <timing-function> <delay>;
}
#delay {
font-size: 14px;
transition-property: font-size;
transition-duration: 4s;
transition-delay: 2s;
}
#delay:hover {
font-size: 36px;
}
.box {
border-style: solid;
border-width: 1px;
display: block;
width: 100px;
height: 100px;
background-color: #0000FF;
transition: width 2s, height 2s, background-color 2s, transform 2s;
}
.box:hover {
background-color: #FFCCCC;
width: 200px;
height: 200px;
transform: rotate(180deg);
}
window.addEventListener('scroll', () => {
let scrollDistance = window.scrollY;
if (window.innerWidth > 768) {
document.querySelectorAll('.section1').forEach((el, i) => {
if (el.offsetTop - document.querySelector('.nav').clientHeight <= scrollDistance) {
document.querySelectorAll('.nav a').forEach((el) => {
if (el.classList.contains('active')) {
el.classList.remove('active');
}
});
document.querySelectorAll('.nav li')[i].querySelector('a').classList.add('active');
}
});
}
});
body {
background: gray;
padding: 100px;
}
.block-2 {
display: flex;
flex-direction: row;
background: white;
width: 100%;
padding: 50px;
height: auto;
}
.section-left {
position: sticky;
top: 10px;
height: 300px;
/* background: gray; */
width: 100%;
}
.section-right {
background: blue;
width: 100%;
}
.wrap {
margin: 10px;
background: red;
}
.content {
height: 500px;
}
.footer {
width: 100%;
height: 700px;
background: red;
}
.nav {
position: relative;
left: 0;
top: 0;
width: 100%;
background-color: white;
/* padding: 20px;
*/
}
.nav ul {
display: flex;
list-style-type: none;
flex-direction: column;
padding: 0;
}
.nav a {
display: flex !important;
text-decoration: none;
color: black !important;
display: inline-block;
/* margin-right: 25px !important;
*/
}
#media screen and (max-width: 1024px) {}
.subtitle {
opacity: 0;
transition:300ms;
}
.subtitle > div {
transition:300ms;
right:100%;
}
.subtitle > div h1 {
opacity:0;
position:relative;
top:2em;
transition:300ms;
transition-delay:1s;
}
.active {
opacity: 1;
}
.active > div {
right:0;
}
.active > div h1 {
opacity:1;
top: 0;
}
.content1 {
position: absolute;
background-color: red;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content2 {
position: absolute;
background-color: gray;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content3 {
position: absolute;
background-color: green;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
.content4 {
position: absolute;
background-color: blue;
/*opacity: 0;*/
width: 100%;
height: 300px;
}
<body>
<div class="block-2">
<div class="section-left">
<nav class="nav">
<ul>
<li><a href="" class="active subtitle">
<div class="content1">
<h1>O1</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content2">
<h1>O2</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content3">
<h1>O3</h1>
</div>
</a></li>
<li><a href="" class="subtitle">
<div class="content4">
<h1>O4</h1>
</div>
</a></li>
</ul>
</nav>
</div>
<div class="section-right">
<div class="section1 wrap">
<div class="content">asdf</div>
</div>
<div class="wrap section1 ">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
<div class="wrap section1">
<div class="content">asdf</div>
</div>
</div>
</div>
<div class="footer"></div>
</body>
I'm trying to make a replica of the slider on top of this google page: https://www.google.com/doodles
If someone could make a replica of the image slider with the bars, that would be great! I've tried to on my own but can't figure it out. Here's my try if it's helpful!
JAVASCRIPT:
<script>
var imgArray = [
'images/img1.gif',
'images/img2.gif',
'images/img3.jpg',
'images/img4.jpg'],
curIndex = 0;
imgDuration = 3000;
function slideShow() {
document.getElementById('slider').className += "fadeOut";
setTimeout(function () {
document.getElementById('slider').src = imgArray[curIndex];
document.getElementById('slider').className = "";
}, 500);
curIndex++;
if (curIndex == imgArray.length) { curIndex = 0; }
}
</script>
HTML:
<img class="slidershow" id="slider" src="images/img1.gif" onmouseover="slideShow()">
<div id="navigation">
<label for="r1" class="bar" id="bar1"></label>
<label for="r2" class="bar" id="bar2"></label>
<label for="r3" class="bar" id="bar3"></label>
<label for="r4" class="bar" id="bar4"></label>
</div>
</div>
CSS: --> Honestly, I wrote so much CSS that I don't know which ones relate, so I might have left a few out. Need to clean that up - Apologize in advance
.nav_links {
list-style: none;
}
.nav_links li {
display: inline-block;
padding: 0px 20px;
}
.nav_links li a {
color: #009cdc;
transition: all 0.3s ease 0s;
}
.nav_links li:hover a {
color: #2772ff;
}
#top-content {
display: block;
}
latest-nav li#latest-nav-1 {
background-color: #fa4842;
}
#latest-nav li.off {
border-top: 15px solid #fff;
}
#latest-nav li.off {
height: 5px;
opacity: 0.35;
}
#latest-nav li {
cursor: pointer;
float: left;
height: 5px;
transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
-moz-transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
-webkit-transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
width: 16.6%;
}
.slidershow {
height: 400px;
overflow: hidden;
}
.middle {
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%,-50%);
}
#navigation {
position: absolute;
bottom: 35px;
left: 60%;
transform: translateX(-50%);
display: flex;
}
.bar {
border-top: 15px solid #fff;
width: 200px;
opacity: 0.35;
height: 5px;
cursor: pointer;
transition: 0.4s;
}
.slides {
width: 500%;
height: 100%;
display: flex;
margin-top: 30px;
}
.slide {
width: 20%;
transition: 0.6s;
}
.slide img {
display: block;
margin: auto;
max-height: 250px;
max-width: 600px;
width: auto;
}
latest .container img {
display: block;
margin: auto;
max-height: 250px;
max-width: 600px;
}
#bar1 {
background-color: #3875fc;
}
#bar2 {
background-color: #ff8809;
}
#bar3 {
background-color: #19be29;
}
#bar4 {
background-color: #fa4842;
}
Thanks so much!
I'm always happy to see newcomers devoting time to study. First of all, good job! Unfortunately I'm not a very good teacher, but I put together a little example of this slider you're working on. You can check it clicking here.
Basically what is going on is:
The HTML is divided into two sections: the slider & the navbar.
I hide all slides by default applying a display: none to them. They're only visible when I add an additional class.
Detect the hover method via javascript. Whenever the navbar item is hovered on, you will detect its position (I added a data attribute called data-position to find out which position it is) and show the correspondent slider.
So, if the navbar has the data-position of 2, I know that I must show the second slide. To do that, I use .slider .slider-item:nth-child(2).
As I mentioned I'm not the best at explaining, but I hope this helps you out a little bit. Keep studying and don't give up!
HTML:
<div class="wrapper">
<div class="slider">
<div class="slider-item slider-item--visible">
hello item 1
</div>
<div class="slider-item">
hello item 2
</div>
<div class="slider-item">
hello item 3
</div>
</div>
<nav class="navbar">
<span class="navbar-item navbar-item--selected" data-position="1"></span>
<span class="navbar-item" data-position="2"></span>
<span class="navbar-item" data-position="3"></span>
</nav>
</div>
CSS
.wrapper{
max-width: 1000px;
width: 100%;
margin: 0 auto;
display: block;
}
/* Slider */
.slider{
max-width: 100%;
width: 100%;
}
.slider-item{
display: none;
}
.slider-item--visible{
display: block;
}
/* Navbar */
.navbar{
max-width: 100%;
display: flex;
align-items: flex-end;
height: 8px;
}
.navbar-item{
max-width: 33.3%;
width: 100%;
display: block;
height: 5px;
cursor: pointer;
opacity: .5;
transition: all .32s ease;
}
.navbar-item--selected{
height: 8px;
opacity: 1;
}
/* Meaningless styles (colors) */
.navbar-item:nth-child(1){
background: salmon;
}
.navbar-item:nth-child(2){
background: lightblue;
}
.navbar-item:nth-child(3){
background: #19be29;
}
Javascript
const $navbars = document.querySelectorAll(`.navbar-item`);
function removeSelected(){
const $selected = document.querySelectorAll(`.navbar-item--selected, .slider-item--visible`);
if (!$selected){
return;
}
for (let each of $selected){
each.classList.remove("navbar-item--selected");
each.classList.remove("slider-item--visible");
}
}
for (let each of $navbars){
each.addEventListener("mouseover", function(){
removeSelected();
const position = each.getAttribute("data-position");
const $item = document.querySelector(`.slider .slider-item:nth-child(${position})`)
each.classList.add("navbar-item--selected")
$item.classList.add("slider-item--visible");
});
}
I'm relatively new to Jquery and I'm trying to make a mouseover transition so when you hover over the title the background image should be changed with some ease css transition but nothing seems to work. I also tried Jquery fadeIn method but that also doesn't seem to work. What's the correct way to make the transition work?
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Roboto;
background-color: #000;
position: relative;
overflow-x: hidden;
transition: all ease 2s;
}
.banner {
width: 100%;
height: 100vh;
transition: all 1s ease;
}
.banner-strip {
display: flex;
height: 100%;
align-items: center;
justify-content: center;
transition: all .5s ease-in-out;
}
.strip {
position: relative;
width: 20%;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 0;
flex-direction: column;
/*background-color: #a03131;*/
color: #fff;
transition: all 1s ease;
}
.strip p {
text-align: center;
}
.strip big {
text-transform: uppercase;
font-size: 24px;
font-weight: 700;
letter-spacing: 2px;
}
.strip img {
line-height: 24px;
font-size: 14px;
text-align: center;
font-style: italic;
opacity: 0;
visibility: hidden;
transition: all ease 2s;
}
.banner-img img {
position: absolute;
width: 100%;
height: 100vh;
opacity: 0;
transition: all .5s ease-in-out;
}
.banner-img {
transtition: all .5s ease-in-out;
}
.strip:hover {
height: 100%;
padding: 15px 0 90px;
transition: all 1s ease;
}
.strip:hover img {
opacity: 1;
visibility: visible;
transition: all ease 2s !important;
}
<body>
<div class="banner">
<div class="banner-img">
<img src="default.jpg" alt="">
</div>
<div class="banner-strip">
<div class="strip" data-image="living.jpg">
<h2>Tattoo</h2><br>
<a href="tattoo.html">
<img src="ikonka4.png" alt="" style="width: 60px; height:60px">
</a>
</div>
<div class="strip" data-image="bedroom.jpg">
<h2>Beauty</h2>
<a href="beauty.html">
<img src="ikonka2.png" alt="" style="width: 60px; height:60px">
</a>
</div>
<div class="strip" data-image="dining.jpg">
<h2>Piercing</h2>
<a href="piercing.html">
<img src="ikonka3.png" alt="" style="width: 60px; height:60px">
</a>
</div>
</div>
</div>
<!-- jquery cdn link -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var image = $(".banner-img").find("img").attr("src");
$(".banner-img img").css("opacity", "1").fadeIn("slow");
$(".strip").mouseover(function() {
var currentImage = $(this).attr("data-image");
$(this).parent().parent().find(".banner-img img").attr("src", currentImage);
$(".banner-img img").fadeIn("slow");
});
$(".strip").mouseout(function() {
$(".banner-img img").fadeIn("slow");
$(".banner-img img").attr("src", image).fadeIn("slow"); // SET DEFAULT IMAGE WHEN MOUSE OUT
});
});
</script>
See example below. I've used the background-color property for example purposes but this can easily be substituted with background-image.
$(function() {
$(".strip").mouseover(function() {
var curImg = $(this).attr("data-image");
$(".banner-img").css("background-color", curImg);
});
$(".strip").mouseout(function() {
$(".banner-img").css("background-color", '#000');
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Roboto;
position: relative;
overflow-x: hidden;
}
.banner {
position: fixed;
width: 100%;
height: 100px;
}
.banner-img {
position: fixed;
width: 100%;
height: 100px;
background-color: #000;
transition: background-color 1s ease-in-out;
}
.banner-strip {
display: flex;
align-items: center;
justify-content: space-around;
}
.strip {
position: relative;
width: 20%;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #fff;
}
.strip img {
display: block;
width: 60px;
height: 60px;
background: #FFF;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.strip:hover img {
opacity: 1;
}
<div class="banner">
<div class="banner-img">
</div>
<div class="banner-strip">
<div class="strip" data-image="red">
<a href="tattoo.html">
<img src="ikonka4.png" alt="">
</a>
<h2>Tattoo</h2>
</div>
<div class="strip" data-image="blue">
<a href="beauty.html">
<img src="ikonka2.png" alt="">
</a>
<h2>Beauty</h2>
</div>
<div class="strip" data-image="green">
<a href="piercing.html">
<img src="ikonka3.png" alt="">
</a>
<h2>Piercing</h2>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
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>
I'm "required" to make a webpage:
In a page I want a side menu and when clicking each option it shows in the right some content, but without "loading" another page (this would be the easier way, just making a page for each "option" and then just clicking in each button would lead me to that page with the content in the right).
I found this:
<script type="text/javascript">
function toggle(IDS) {
var sel = document.getElementById('pg').getElementsByTagName('div');
for (var i=0; i<sel.length; i++) {
if (sel[i].id != IDS) { sel[i].style.display = 'none'; }
}
var status = document.getElementById(IDS).style.display;
if (status == 'block') { document.getElementById(IDS).style.display = 'none'; }
else { document.getElementById(IDS).style.display = 'block'; }
return false;
}
</script>
I just added it to the side menu and when each part is clicked it shows what I want :
<div id="sidebar2">
<div>
<h2 class="title">TEXT</h2>
<ul>
<li>TEXT</li>
<li>TEXT2</li>
</ul>
</div>
<div>
And in the content of each "option":
<div id="pg">
<div id="pg0" class="pg">
<h2 class="title">TEXT</h2>
<p><img src="images/test.png" alt=""/></p>
</div>
<div id="pg1" class="pg">
<h2 class="title">TEXT2</h2>
<p><img src="images/test2.png" alt=""/>HERE GOES THE DIV POPUP BUTTON</p>
</div>
I want a button to open a pop up image. It appears toggle() sets everything inside each div to display:none; and when I click only changes to block the outer part. But if I have a div inside, it remains hidden.
I've tried these two codes for the popup:
<div id="test">
<a href="#" class="JesterBox">
<div id="image1"><img src="bg.jpg"></div>
</a>
Image 1
With the corresponding JesterBox definition in CSS:
.JesterBox div {
visibility: hidden;
position: fixed;
top: 5%;
right: 5%;
bottom: 5%;
left: 5%;
z-index: 75;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.JesterBox div:before {
content: '';
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 74;
background-color: rgba(0, 0, 0, 0);
transition: all 0.5s ease-out;
}
.JesterBox div img {
position: relative;
z-index: 77;
max-width: 100%;
max-height: 100%;
margin-left: -9999px;
opacity: 0;
transition-property: all, opacity;
transition-duration: 0.5s, 0.2s;
transition-timing-function: ease-in-out, ease-out;
}
.JesterBox div:target { visibility: visible; }
.JesterBox div:target:before { background-color: rgba(0, 0, 0, 0.7); }
.JesterBox div:target img {
margin-left: 0px;
opacity: 1;
}
And this other:
<div class="box">
<a class="button" href="#popup1">TEXT</a>
</div>
<div id="popup1" class="overlay">
<div class="popup">
<h2>Title</h2>
<a class="close" href="#">×</a>
<div class="content">
TEXT TEXT
</div>
</div>
</div>
With its corresponding CSS:
.box {
width: 20%;
margin: 0 auto;
background: rgba(255,255,255,0.2);
padding: 35px;
border: 2px solid #fff;
border-radius: 20px/50px;
background-clip: padding-box;
text-align: center;
}
.button {
font-size: 1em;
padding: 10px;
color: #fff;
border: 2px solid #06D85F;
border-radius: 20px/50px;
text-decoration: none;
cursor: pointer;
transition: all 0.3s ease-out;
}
.button:hover {
background: #06D85F;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 30%;
position: relative;
transition: all 5s ease-in-out;
}
.popup h2 {
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.popup .close:hover {
color: #06D85F;
}
.popup .content {
max-height: 30%;
overflow: auto;
}
#media screen and (max-width: 700px){
.box{
width: 70%;
}
.popup{
width: 70%;
}
}
I can't make it work. How could I make, for example, the 2nd option (the div class="box") work inside the div?
<div id="pg1" class="pg">
<h2 class="title">TEXT2</h2>
<p>
<div class="box">
<a class="button" href="#popup1">TEXT</a>
</div>
<div id="popup1" class="overlay">
<div class="popup">
<h2>Title</h2>
<a class="close" href="#">×</a>
<div class="content">
TEXT TEXT
</div>
</div>
</div>