Javascript image slider not working properly - javascript

I'm trying to create an image slider with controls "Next" and "Previous". Next should slide the image left using a negative margin-left property so as to reveal the second image. All the list elements holding individual images are set to display: inline-block so each list element can stand next to each other instead of stacking.
However, I found out that when the first image slides left it still reveals a little out of it while showing the second image, on and on and on like that, everything slides but never fully. the distance they slide is equal to the width of the image.
Also, when I get to the last image and click on next it should go back to the first image, the problem is that it displays each image along the way to the first image.
window.onload = function () {
var nextBtn = document.getElementsByClassName("nextBtn")[0],
prevBtn = document.getElementsByClassName("prevBtn")[0];
var i = 0;
var imgList = document.querySelectorAll(".slide");
var slideLength = imgList.length;
var lastchild = imgList[slideLength - 1];
nextBtn.addEventListener("click", Next, false);
prevBtn.addEventListener("click", Previous, false);
function Next() {
console.log(slideLength)
imgList[i].style.marginLeft = "-600px";
if (imgList[i].classList.contains("active")) {
imgList[i].classList.remove("active");
}
if (imgList[i] !== lastchild) {
i++;
}
else if (imgList[i] === lastchild) {
i = 0;
for (var j = 0; j < slideLength; j++) {
imgList[j].style.marginLeft = "0";
}
}
imgList[i].classList.add("active");
}
function Previous(e) {
console.log(i);
if (i !== 0) {
imgList[i - 1].style.marginLeft = "0";
i--;
console.log(i);
}
else {
console.log(i);
}
}
}
ul{
width: 100%;
height: 350px;
border: solid 3px white;
margin:100px auto;
overflow: hidden;
}
li{
display:inline-block;
position: relative;
transition: all 1s cubic-bezier(1,-0.01, 0, 1.13);
list-style: none;
}
li img{
width:600px;
height:350px
}
.slide h2{
position: absolute;
bottom:80px;
text-align: center;
margin: 0 auto;
left: 250px;
color: #fff;
font-size: 4em;
font-weight: 900;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<ul class="slide-wrapper">
<li class="slide active">
<img src="http://placehold.it/350x150" alt="">
<h2>1</h2>
</li>
<li class="slide">
<img src="http://placehold.it/350x150" alt="">
<h2>2</h2>
</li>
<li class="slide">
<img src="http://placehold.it/350x150" alt="">
<h2>3</h2>
</li>
<li class="slide">
<img src="http://placehold.it/350x150" alt="">
<h2>4</h2>
</li>
<li class="slide">
<img src="http://placehold.it/350x150" alt="">
<h2>5</h2>
</li>
</ul>
</div>
<!--<div class="test">
</div>-->
<button class="nextBtn">Next</button>
<button class="prevBtn">Previous</button>
How can I make this work well strictly with vanilla javascript? Here is the link to the jsfiddle . However, it doesn't seem to work at all there.

Reference : https://jsfiddle.net/a2bk4bwu/3/
Replace your CSS with lines with the for ul & li
ul{
width: 100%;
height: 350px;
border: solid 3px white;
margin:100px auto;
overflow: hidden;
padding-left: 0;
font-size: 0px;
}
li{
font-size : 20px;
display:inline-block;
position: relative;
transition: all 1s cubic-bezier(1,-0.01, 0, 1.13);
list-style: none;
}
Things to note :
'Ul' was taking extra padding by default {webkit-padding-start: 40px}
"display : inline-block" items are dependent on "white-space". So give "0px" to the parent element to remove that white space between slides.
These will fix your CSS issues.

Related

Show content based on active link in nav bar

I created three active links using CSS and javascript. I have three data sets in forms of image that I want to show based on which link is active. The images will be below the link in form of swiper slides. How I do this? My reference for this is the active slide on new balances website
.active-link {
position: relative;
display: flex;
top: 12rem;
/*position for active link */
justify-content: center;
}
.button {
padding: 0 40px 10px 40px;
cursor: pointer;
display: inline-block;
font-weight: 500;
border-bottom: 2px solid black;
}
.button:active,
.active {
color: red;
border-bottom: 5px solid red;
padding-bottom: 7px;
}
.slide-container {
position: relative;
// I'm not sure what you're looking for visually so I just used a top position greater than what you're already using on the buttons.
top: 14rem;
display: none;
}
.slide-container.active {
display: block;
}
<div class="active-link" id="active-link">
<li>
<a class="button">Him</a>
</li>
<li>
<a class="button active">2</a>
</li>
<li>
<a class="button">Her</a>
</li>
</div>
<div class="slide-containers">
<div id="slide-container-1" class="slide-container">
Slide Container 1
</div>
<div id="slide-container-2" class="slide-container">
Slide Container 2
</div>
<div id="slide-container-3" class="slide-container">
Slide Container 3
</div>
</div>
<script>
var btnContainer = document.getElementById("active-link");
var btns = btnContainer.getElementsByClassName("button");
function removeClass(elems, className) {
[].forEach.call(document.querySelectorAll(elems), function(el) {
el.classList.remove(className);
});
}
const resetSlideContainers = () => {
[...document.querySelectorAll('.slide-container')].forEach((slide) =>
slide.classList.remove('active'));
}
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function(e) {
removeClass('.button', 'active')
this.classList.toggle('active');
resetSlideContainers();
document.getElementById(this.getAttribute('data-slide')).classList.add('active');
})
}
</script>
I created three active links using CSS and javascript. I have three data sets in forms of image that I want to show based on which link is active. The images will be below the link in form of swiper slides. How I do this? My reference for this is the active slide on new balances website
var btnContainer = document.getElementById("active-link");
var btns = btnContainer.getElementsByClassName("button");
function removeClass(elems, className) {
[].forEach.call(document.querySelectorAll(elems), function(el) {
el.classList.remove(className);
});
}
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function(e) {
removeClass('.button', 'active')
this.classList.toggle('active');
})
}
.active-link {
position: relative;
display: flex;
top: 12rem;
justify-content: center;
}
.button {
padding: 0 40px 10px 40px;
cursor: pointer;
display: inline-block;
font-weight: 500;
border-bottom: 2px solid black;
}
.button:active,
.active {
color: red;
border-bottom: 5px solid blue;
padding-bottom: 7px;
}
<div class="active-link" id="active-link">
<li>
<a class="button">1</a>
</li>
<li>
<a class="button active">2</a>
</li>
<li>
<a class="button">3</a>
</li>
</div>
I would create a container to hold the contents of each slide and link buttons to a slide using a data attribute. When a button is clicked, you can remove the active class of the previous slide and add a new one for the current slide. Here is the relevant code that I added with a Codepen link at the bottom.
<div class="active-link" id="active-link">
<li>
<a class="button" data-slide="slide-container-1">1</a>
</li>
<li>
<a class="button active" data-slide="slide-container-2">2</a>
</li>
<li>
<a class="button" data-slide="slide-container-3">3</a>
</li>
</div>
<div class="slide-containers">
<div id="slide-container-1" class="slide-container">
Slide Container 1
</div>
<div id="slide-container-2" class="slide-container">
Slide Container 2
</div>
<div id="slide-container-3" class="slide-container">
Slide Container 3
</div>
</div>
.slide-container {
position: relative;
// I'm not sure what you're looking for visually so I just used a top position greater than what you're already using on the buttons.
top: 14rem;
display: none;
}
.slide-container.active {
display: block;
}
const resetSlideContainers = () => {
[ ...document.querySelectorAll('.slide-container') ].forEach((slide) => slide.classList.remove('active'));
}
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function(e) {
removeClass('.button', 'active')
this.classList.toggle('active');
resetSlideContainers();
document.getElementById(this.getAttribute('data-slide')).classList.add('active');
})
}
Here is a working example.

How to create horizontal carousel in JavaScript?

Goal: To create a carousel effect when switching between items laid out in a list. Consider the following HTML structure:
<div class="container">
<ul class="gallery">
<li class="slide">
<!-- Some content -->
</li>
<li class="slide">
<!-- Some content -->
</li>
<!-- Some more items -->
</ul>
</div>
Initially, the list gallery should be centered inside the container, with each list item slide stacked on top of each other. After populating the slides with relevant data, the first slide should be made active, while the second slide be scaled a bit smaller and less opaque (among other styling that shows that this slide is not active, but in queue). All the other slides should be hidden.
Now, clicking on any item (slide) - except for the active one - should trigger the carousel effect, which looks similar to this implementation by GreenSock (The difference is that, first their implementation is dependent on scrolling through mouse-wheel, whereas, I want the effect to take place on clicking an item. Also, their implementation requires the use of third-party library GSAP and ScrollTrigger, but I do not want to use either of them - only plain DOM manipulation. Additionally, they have infinite scroll but I do not want to circle back to the other end when list is finished in either end.)
To create a 3-item carousel effect, we define five possible states for our slide:
lhidden (hidden on the leftmost side)
lqueue (in queue on the left side)
active (the currently active slide)
rqueue (in queue on the right side)
rhidden (hidden on the rightmost side)
The styling for these five states makes use of CSS opacity, z-index, and transform properties.
.slide.active {
opacity: 1;
z-index: 2;
transform: translate(0px) scale(1);
}
.slide.lqueue {
opacity: 0.64;
z-index: 1;
transform: translate(-100%) scale(0.64);
}
.slide.rqueue {
opacity: 0.64;
z-index: 1;
transform: translate(100%) scale(0.64);
}
.slide.lhidden {
opacity: 0;
z-index: auto;
transform: translate(-160%) scale(0);
}
.slide.rhidden {
opacity: 0;
z-index: auto;
transform: translate(160%) scale(0);
}
To place the list gallery in center of the container, we use flex display on container and set its align-center and justify-content to center. Then, to make so that each item in the list is stacked on top of each other in the same place, we set relative position on the list, and absolute position on each item, with top margin equal to 0.
.container {
display: flex;
align-items: center;
justify-content: center;
}
..gallery {
position: relative;
width: 400px; /* Can be anything */
height: 650px; /* Can be anything */
list-style: none;
}
.slide {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
In the JavaScript, we iterate over each slide and set add rhidden to their class list. After which, we manually set the first slide to have active and the second slide to have rqueue class respectively. Then, we attach an event listener to the click event on each slide, passing its index as argument, so that we can manipulate its immediate siblings to achieve the carousel effect.
function initializeCarousel(){
const slides = document.querySelectorAll(".slide");
for (let index = 0; index < slides.length; index++) {
const slide = slides[index];
slide.classList.add("rhidden");
slide.addEventListener("click", () => {
activateCarousel(index);
});
}
slides[0].classList = "slide active";
slides[1].classList = "slide rqueue";
}
We can only click on three types of slides since we cannot click on hidden ones:
active
lqueue
rqueue
If we clicked on active slide, we need to do nothing and simply return.
If we clicked on either lqueue or rqueue slide, we set itself to be active, and make its surrounding siblings have queue and hidden states based on its index difference from the clicked slide.
function activateCarousel(index) {
const slides = document.querySelectorAll(".slide");
const slide = slides[index];
if (slide.classList.contains("active")) {
return;
}
slide.classList = "slide active";
if (slides[index - 2] != undefined) {
slides[index - 2].classList = "slide lhidden";
}
if (slides[index - 1] != undefined) {
slides[index - 1].classList = "slide lqueue";
}
if (slides[index + 1] != undefined) {
slides[index + 1].classList = "slide rqueue";
}
if (slides[index + 2] != undefined) {
slides[index + 2].classList = "slide rhidden";
}
}
A complete implementation should look like the following snippet.
function activateCarousel(index) {
const slides = document.querySelectorAll(".slide");
const slide = slides[index];
if (slide.classList.contains("active")) {
return;
}
slide.classList = "slide active";
if (slides[index - 2] != undefined) {
slides[index - 2].classList = "slide lhidden";
}
if (slides[index - 1] != undefined) {
slides[index - 1].classList = "slide lqueue";
}
if (slides[index + 1] != undefined) {
slides[index + 1].classList = "slide rqueue";
}
if (slides[index + 2] != undefined) {
slides[index + 2].classList = "slide rhidden";
}
}
function initializeCarousel() {
const slides = document.querySelectorAll(".slide");
for (let index = 0; index < slides.length; index++) {
const slide = slides[index];
slide.classList.add("rhidden");
slide.addEventListener("click", () => {
activateCarousel(index);
});
}
slides[0].classList = "slide active";
slides[1].classList = "slide rqueue";
}
initializeCarousel();
/* Root structure */
:root {
--color-primary: #1a1a1d;
--color-secondary: #955d80;
--color-tertiary: #d3b6bf;
}
*,
*::before,
*::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.container {
height: 100vh;
background-image: linear-gradient(180deg, #ce0240, #a80135);
display: flex;
align-items: center;
justify-content: center;
}
/* Gallery list layout */
.gallery {
position: relative;
width: 400px;
height: 650px;
list-style: none;
}
/* Individual item a.k.a "slide" structure */
.slide {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(180deg, #ffe9e3, #ffe9e3);
border-radius: 25px;
padding: 50px;
display: flex;
gap: 0.5rem;
flex-direction: column;
align-items: center;
transition: all 0.3s;
}
/* Slide states */
.slide.active {
opacity: 1;
z-index: 2;
transform: translate(0px) scale(1);
}
.slide.lqueue {
opacity: 0.64;
z-index: 1;
transform: translate(-100%) scale(0.64);
}
.slide.rqueue {
opacity: 0.64;
z-index: 1;
transform: translate(100%) scale(0.64);
}
.slide.lhidden {
opacity: 0;
z-index: auto;
transform: translate(-160%) scale(0);
}
.slide.rhidden {
opacity: 0;
z-index: auto;
transform: translate(160%) scale(0);
}
.slide.lqueue *,
.slide.rqueue *,
.slide.lhidden *,
.slide.rhidden * {
pointer-events: none;
}
.slide.lqueue *::selection,
.slide.rqueue *::selection,
.slide.lhidden *::selection,
.slide.rhidden *::selection {
background-color: transparent;
}
/* Slide specifics */
.slide--picture {
width: 300px;
height: 320px;
object-position: top;
object-fit: cover;
border-radius: 25px;
box-shadow: -10px 10px 60px #ce0240;
margin-bottom: 30px;
}
.slide--name,
.slide--description {
width: 100%;
text-align: left;
font-weight: bold;
}
.slide--name {
color: var(--color-primary);
font-size: 1.6rem;
}
.slide--description {
font-size: 1rem;
color: var(--color-secondary);
}
<main class="container">
<ul class="gallery">
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/l0TNFUosa_avatar-Ex0lN8A5U.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Puff Johnson</h2>
<p class="slide--description">NCAA Basketball - North Carolina Tar Heels</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/JbSCP9pbj_avatar-A3Pby19td.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Maddie Poppe</h2>
<p class="slide--description">American Idol Season 16 Winner</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/Sa_09kTuP_avatar-76TOucMti.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Justin Roberts</h2>
<p class="slide--description">Ring Announcer & MC - AEW</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/t8EJJ9Ef4M_avatar-5xB9jXzKl.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Brodie That Dood</h2>
<p class="slide--description">Viral Star - Brodie The Goldendoodle</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/IPFAWngd3_avatar-_XExw5Daa.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Tony Vitello</h2>
<p class="slide--description">Tennessee Baseball Coach</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/hl_Vh7TFN_avatar-Y12cyyBbB.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Omar Narvaez</h2>
<p class="slide--description">MLB - Milwaukee Brewers</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/1xY4Ue6wb_avatar-aR2of-zCB.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Jordan Schlansky</h2>
<p class="slide--description">Associate Producer - The Conan O'Brien Show</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/Zs7_MjEtl_93Kxr22tk.png?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Colin Mochrie</h2>
<p class="slide--description">Comedian - Whose Line is it Anyway?</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/GrFxbkTTT_PBhuEqlck.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Tommy Chong</h2>
<p class="slide--description">Comedian - Musician - Actor - Writer</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/QQ-agNUb8_27456_001_002_0073_R.JPG?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">James Murray</h2>
<p class="slide--description">TruTV - Impractical Jokers</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/gxtdQlFH2_avatar-snpKtIVyV.png?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Fortune Feimster</h2>
<p class="slide--description">Actress - Comedian</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/IH6BNRNN1_5F746EBF-BB49-43F6-9EC7-51B4FF831859.jpeg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Andrew Dice Clay</h2>
<p class="slide--description">Comedian</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/X85ZZzwEE_IMG_09552.JPG?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Anthony Anderson</h2>
<p class="slide--description">Actor - Black-ish</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/MdckbEzZy_35105081995_5d36db665a_k.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Fiona the Hippo</h2>
<p class="slide--description">Animals - Cincinnati Zoo</p>
</li>
<li class="slide">
<img class="slide--picture" src="https://d31wcbk3iidrjq.cloudfront.net/8VF6SrNzw_avatar-jowRSkmuT.jpg?h=320&w=300&q=100" alt="Slide picture">
<h2 class="slide--name">Susie Essman</h2>
<p class="slide--description">HBO - Curb Your Enthusiasm</p>
</li>
</ul>
</main>

Adding more than one javascript image slider on same page

I want more than one image slider on same page with same class name using JavaScript. I have done for one image slider.
The issues are when I'm using more than one image slider it is not working properly.I tried with childNodes also it doesn't work. How can I solve this problem?
And I'm trying to make sliding animation also(left and right) for that image slider.
If you need some more explanation, let me know.
I have given the code below;
HTML
<div class="container slider">
<div class="slides">
<img src="images-/b3.jpg">
</div>
<div class="slides">
<img src="images-/b2.jpg">
</div>
<div class="slides">
<img src="images-/b1.jpg">
</div>
<a class="prev" onclick="controlSlide(-1)">❮</a>
<a class="next" onclick="controlSlide(1)">❯</a>
</div>
<div class="container slider">
<div class="slides">
<img src="images-/b3.jpg">
</div>
<div class="slides">
<img src="images-/b2.jpg">
</div>
<div class="slides">
<img src="images-/b1.jpg">
</div>
<a class="prev" onclick="controlSlide(-1)">❮</a>
<a class="next" onclick="controlSlide(1)">❯</a>
</div>
CSS
.slides{
position: relative;
display:none;
}
img{
width: 100%;
vertical-align:middle;
}
.container
{
max-width: 100%;
position: relative;
margin: auto;
}
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
color: black;
font-size: 20px;
}
.prev{
left: 2%;
}
.next{
right: 2%;
}
.prev:hover, .next:hover {
background-color: #f1f1f1;
text-decoration: none;
color: black;
}
JAVASCRIPT
var slides = document.getElementsByClassName("slides");
var position=[1,-1];
var slideIndex=0;
showSlides();
function showSlides() {
controlSlide(position[0]);
setTimeout(showSlides,3000);
}
function controlSlide(position) {
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex +=position;
if (slideIndex>slides.length) {
slideIndex = 1;
}
else if(slideIndex<=0){
slideIndex=slides.length;
}
slides[slideIndex-1].style.display= "block";
}
The problem is that you select all the slides at once, with document.getElementsByClassName("slides").
You want to alter you JS methods to work with the sorrounding element
<div class="container slider">
and then select and pass theese to controlSlide form showSlides.
Not tested:
var sliders = document.getElementsByClassName("slider");
var position=[1,-1];
var slideIndex=0;
sliders.forEach(function(slider){
showSlides(slider);
})
function showSlides(slider) {
let slides = slider.childNodes;
controlSlide(slides, position[0]);
setTimeout(showSlides,3000);
}
function controlSlide(slides, position) {
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex +=position;
if (slideIndex>slides.length) {
slideIndex = 1;
}
else if(slideIndex<=0){
slideIndex=slides.length;
}
slides[slideIndex-1].style.display= "block";
}

slidetoggle in pure Javascript

As you might see I have fixed a kind of text box that will pop up when someone is hovering over that image, but honestly I want a slide-up effect that gone up slowly. Must be completely in pure JavaScript (no jQuery please!). Anyone knows how I can do that.
function show(myText) {
var elements = document.getElementsByClassName(myText)
for(var i = 0; i < elements.length; i++){
elements[i].style.visibility = "visible";
}
}
function hide(myText) {
var elements = document.getElementsByClassName(myText)
for(var i = 0; i < elements.length; i++){
elements[i].style.visibility = "hidden";
}
}
.text1 {
position: relative;
bottom: 28px;
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
visibility: hidden;
}
.text2 {
position: relative;
bottom: 28px;
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
visibility: hidden;
}
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.bbc.com" target="_blank" class="image" onmouseover="show('text1')" onmouseout="hide('text1')">
<img src="https://i.vimeocdn.com/portrait/8070603_300x300" class="project" alt="print-screen"/>
<div class="text1">AAA</div>
</a>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.cnn.com" target="_blank" class="image" onmouseover="show('text2')" onmouseout="hide('text2')">
<img src="https://lh6.ggpht.com/mSKQgjFfPzrjqrG_d33TQZsDecOoVRF-jPKaMDoGIpMLLT1Q09ABicrXdQH6AZpLERY=w300" class="project" alt="print-screen"/>
<div class="text2">BBB</div>
</a>
</div>
</div>
</div>
Here is a version of it that's totally javascript free, just using CSS. I'm going to edit this soon with a slight javascript addition (this current version requires you to have a fixed size).
.caption {
height: 250px;
width: 355px;
overflow: hidden;
}
.caption-image {
height: 100%;
}
.caption-text {
color: white;
padding: 10px;
background: rgba(0, 0, 0, 0.4);
transition: transform 400ms ease;
}
.caption-image:hover + .caption-text,
.caption-text:hover {
transform: translateY(-100%);
}
<div class="caption">
<img class="caption-image" src="http://faron.eu/wp-content/uploads/2013/05/Cheese.jpg" />
<div class="caption-text">Some words about how cheesy it is to use a picture of cheese for this example!</div>
</div>
<div class="caption">
<img class="caption-image" src="https://top5ofanything.com/uploads/2015/05/Tomatoes.jpg" />
<div class="caption-text">There's nothing witty to say about a tomato, maybe some you say I say stuff. But honstly I can't think of anything...</div>
</div>
Version with JS sizing:
Basically the same idea, but when the page is loading it sets certain styles so the images can be what ever size you like.
var captionSel = document.querySelectorAll('.caption');
for (let i = 0; i < captionSel.length; i++) {
let image = captionSel[i].querySelector(":scope > .caption-image");
let text = captionSel[i].querySelector(":scope > .caption-text");
text.style.width = image.clientWidth - 20 + "px";
captionSel[i].style.height = image.clientHeight + "px";
}
.caption {
overflow: hidden;
}
.caption-text {
color: white;
padding: 10px;
background: rgba(0, 0, 0, 0.4);
transition: transform 400ms ease;
}
.caption-image:hover + .caption-text,
.caption-text:hover {
transform: translateY(-100%);
}
<div class="caption">
<img class="caption-image" src="http://faron.eu/wp-content/uploads/2013/05/Cheese.jpg" />
<div class="caption-text">Some words about how cheesy it is to use a picture of cheese for this example!</div>
</div>
<div class="caption">
<img class="caption-image" src="https://top5ofanything.com/uploads/2015/05/Tomatoes.jpg" />
<div class="caption-text">There's nothing witty to say about a tomato, maybe some you say I say stuff. But honstly I can't think of anything...</div>
</div>
I'll give it to you even better: No javascript at all!
This is possible with pure CSS:
.tumb-wrapper {
position: relative;
overflow: hidden;
}
.text {
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
position: absolute;
bottom: -30px;
transition: 300ms;
left: 0;
}
.tumb-wrapper:hover .text {
bottom: 28px;
}
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.bbc.com" target="_blank" class="image">
<img src="https://i.vimeocdn.com/portrait/8070603_300x300" class="project" alt="print-screen"/>
<div class="text">AAA</div>
</a>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.cnn.com" target="_blank" class="image">
<img src="https://lh6.ggpht.com/mSKQgjFfPzrjqrG_d33TQZsDecOoVRF-jPKaMDoGIpMLLT1Q09ABicrXdQH6AZpLERY=w300" class="project" alt="print-screen"/>
<div class="text">BBB</div>
</a>
</div>
</div>
</div>
The transition css property animates whatever change you make. This way, when you hover over the .tumb-wrapper div, the .text div will slide up.
You should note however, that ancient IE versions won't be able to use this
I usually do this with only CSS.
Just save the first and second image right next to each other on one file... then you use css to change the position of the background image. To make things nicer i add a css-animation to the movement of the background image.
Example of my code:
<div id="thumb_Wrapper">
<div class="_Thumb">
<img src="images/Thumb.jpg" class="Animate_left">
</div>
</div>
The CSS
#_Container{position:absolute; bottom -60px; right:2px; width:626px; height:100px;}
._Thumb{position:relative; margin-right:4px; width:100px; height:80px; display:block; float:left; background:#EFEFEF; overflow:hidden;}
._Thumb > img{position:absolute; left:0; height:100%; background-size:cover; background-position:center;}
._Thumb > img:hover{left:-18px; cursor:pointer;}
CSS Animation
.Animate_left{transition:left .3s;}
Now all you have to do is swap out the image.
onHover - the image in the thumbnail will smoothly slide to the left; revealing the rest of the image/ showing the other image.
You can set how far to the left(or right) you want the thumb-image to first appear by adjusting the value of 'left' in the ._Thumb class.
You can set how far the image slides on hover by adjusting the img:hover{left:-18px} to what ever you like; instead of 18px.

Add hover and thumbnail support with jQuery

Here is my code I'm using: http://plnkr.co/edit/qfL6mg3bUGYxX70dx1WV?p=preview
I'm trying to figure out how I can pause the slideshow when a user hovers over the large slider image and also, if the user clicks on a thumbnail how can I add the "selected" class like the first image with the blue border has?
Here is the html:
<div id="slider-container">
<ul class="slider">
<li>
<img src="http://placehold.it/350x150&text=1">
<div class="img-caption">
<h2>Test1</h2>
<p>Test 1 text</p>
</div>
</li>
<li>
<img src="http://placehold.it/350x150&text=2">
<div class="img-caption">
<h2>Test2</h2>
<p>Test 2 text</p>
</div>
</li>
<li>
<img src="http://placehold.it/350x150&text=3">
<div class="img-caption">
<h2>Test3</h2>
<p>Test 3 text</p>
</div>
</li>
<li>
<img src="http://placehold.it/350x150&text=4">
<div class="img-caption">
<h2>Test4</h2>
<p>Test 4 text</p>
</div>
</li>
</ul>
<!--/main slider slider-->
<!-- thumb navigation slider -->
<div id="slider-thumbs">
<!-- thumb navigation slider items -->
<ul class="list-inline">
<li> <a class="selected">
<img src="http://placehold.it/50x50&text=1">
</a></li>
<li> <a>
<img src="http://placehold.it/50x50&text=2">
</a></li>
<li> <a>
<img src="http://placehold.it/50x50&text=3">
</a></li>
<li> <a>
<img src="http://placehold.it/50x50&text=4">
</a></li>
</ul>
</div>
</div>
CSS:
#slider-container {
float: left;
}
.slider {
position: relative;
overflow: hidden;
margin: 0px;
padding: 0;
}
.slider li {
display: none;
top: 0;
left: 0;
list-style: none;
}
.img-caption {
background-color: #e3e4e4;
opacity: 0.8;
margin-top: -100px;
padding: 0px 0 0px 15px;
}
.img-caption h2 {
font-size: 28px;
text-transform: uppercase;
padding-top: 10px;
}
.img-caption p {
font-size: 14px;
margin-top: -20px;
padding-bottom: 10px;
}
.list-inline {
padding-left: 0;
list-style: none;
}
.list-inline>li {
display: inline-block;
padding-left: 1px;
padding-right: 1px;
}
.selected img {
border: 3px #0084d9 solid;
}
#slider-thumbs {
margin-top: -20px;
}
And JS:
jQuery(function($) {
var $slider = $('.slider');
var $slide = 'li';
var $transition_time = 0;
var $time_between_slides = 4000;
function slides(){
return $slider.find($slide);
}
slides().fadeOut();
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
$interval = setInterval(
function(){
var $i = $slider.find($slide + '.active').index();
slides().eq($i).removeClass('active');
slides().eq($i).fadeOut($transition_time);
if (slides().length == $i + 1) $i = -1;
slides().eq($i + 1).fadeIn($transition_time);
slides().eq($i + 1).addClass('active');
}
, $transition_time + $time_between_slides
);
});
If you have any question let me know before down voting. I'll do my best for clarification. Thx
This should do : http://plnkr.co/edit/X2I1AFo2O1KOnnnBMiUg?p=preview
Thumbs are selected as slides are activated.
On user click thumbs are selected and same slide is activated.
On hover no action. (Thom-x's answer)
$("#slider-thumbs li a").click(function() {
var $i = $slider.find($slide + '.active').index();
slides().eq($i).removeClass('active');
slides().eq($i).fadeOut($transition_time);
var $j = $thumbs.find('li a.selected').parent().index();
thumbslist().eq($j).removeClass('selected');
$j = $(this).parent().index();
slides().eq($j).fadeIn($transition_time);
slides().eq($j).addClass('active');
$(this).addClass("selected");
});
I used :
$(".slider").hover(callback,callback)
Now you can pause the slider.
http://plnkr.co/edit/Qe3qq6v5g2FU3dVerUMc?p=preview
Edit :
Everything is working now (with some basic Jquery functions).

Categories

Resources