Javascript Images Cycle on Hover - javascript

I'm new to coding and would like to adapt a code I got from CodePen for my website.
It is to hover over an image and the images below will automatically cycle.
However this code works for only one set of images and doesn't work if I have two sets of images.
I would really like to learn why please??? Thank you.
<html>
<style>
.js-animated figure.active {
opacity: 1;
}
.image-deck {
position: relative;
height: 12rem;
width: 18rem;
}
.image-deck figure {
opacity: 0;
height: 100%;
width: 100%;
position: absolute;
}
.image-deck figure img {
height: 100%;
width: 100%;
}
</style>
<body>
<!--Working-->
<div class="image-deck js-animated">
<figure>
<img src="https://picsum.photos/300/300">
</figure>
<figure>
<img src="https://picsum.photos/301/301">
</figure>
<figure>
<img src="https://picsum.photos/302/302">
</figure>
<figure>
<img src="https://picsum.photos/303/303">
</figure>
</div>
<!--Not Working-->
<div class="image-deck js-animated">
<figure>
<img src="https://picsum.photos/304/304">
</figure>
<figure>
<img src="https://picsum.photos/305/305">
</figure>
<figure>
<img src="https://picsum.photos/306/306">
</figure>
<figure>
<img src="https://picsum.photos/307/307">
</figure>
</div>
</body>
<script>
// get the image wrapper
const imageDeck = document.querySelector(".image-deck.js-animated");
// get the set of images within the wrapper
const images = imageDeck.children;
// reveal the first image
images[0].classList.add("active");
// set up the iterator
let i = 0;
// set up the function that we will call from our repeater
function cyclePhotos() {
// remove the active class from the current image
images[i].classList.remove("active");
// if the iterator is less than the total number of images
// go to the next number, otherwise reset to 0
i = i + 1 < images.length ? i + 1 : 0;
// add the active class to the next image
images[i].classList.add("active");
}
// instantiate the repeater
let repeater;
// when you hover over the image wrapper, start the reapeater
// repeat every 500ms
imageDeck.addEventListener("mouseover", (e) => {
repeater = setInterval(cyclePhotos, 500);
});
// when you are no longer hovering, clear the repeater
imageDeck.addEventListener("mouseout", (e) => {
clearInterval(repeater);
});
</script>
</html>

Related

How can I add css class to the to the nested element using DOM?

I have four child divs inside the container div, every child div has a button, image, and text inside. Images have to be blurry and text has to be hidden by default.
And when the user clicks the button, the button should be hidden, image and text should become clear and visible.
I'm trying to add or remove CSS classes from elements using for loop, but that just doesn't work at all...
let btns = document.querySelectorAll(".btn");
let images = document.querySelectorAll(".img");
let imgTexts = document.querySelectorAll(".img-text");
images.forEach((el) => el.classList.add("blur"));
imgTexts.forEach((el) => el.classList.add("hidden"));
for (let i = 0; i < btns; i++) {
btns[i].addEventListener("click", function () {
btns[i].classList.add("hidden");
});
}
.blur {
filter: blur(8px);
-webkit-filter: blur(8px);
}
.hidden {
display: none;
}
<div class="container">
<div class="card">
<button class="btn">Open the Gift</button>
<img
src=""
alt="#" class="img">
<p class="img-text">CONGRATULATIONS🎉</p>
</div>
<div class="card">
<button class="btn">Open the Gift</button>
<img
src=""
alt="#" class="img">
<p class="img-text">CONGRATULATIONS🎉</p>
</div>
<div class="card">
<button class="btn">Open the Gift</button>
<img
src=""
alt="#" class="img">
<p class="img-text">CONGRATULATIONS🎉</p>
</div>
<div class="card">
<button class="btn">Open the Gift</button>
<img
src=""
alt="#" class="img">
<p class="img-text">CONGRATULATIONS🎉</p>
</div>
</div>
for (let i = 0; i < btns; i++) {
btns[i].addEventListener("click", function () {
btns[i].classList.add("hidden");
});
}
Here, in the conditions of the for loop, write "i < btns.length".
There is not a boundation that you can create only one class. You can create multiple classes and just on and add and remove the class according to your need.
example code
HTML
<img class = "image imageHidden" src = alt = >
<button class = "button buttonHidden">Click me</button>
now I created two classes at the same time I can use them to my need in javascript
CSS
.image {
visiblity: visible}
.imageHidden {
visibility: hidden}
.button {
visibility: visible}
.buttonHidden {
visibility: hidden}
now I used them in CSS that I can use in javascript
document.querySelector(".button").addEventListener("click",function () {
document.querySelector("img").classList.add("image");
document.querySelector("button").classList.add("buttonHidden");});
this code will hide the button and show the image you can use this method according to your need.

adding previous/next slide event listeners for modal lightbox (Javascript)

I'm building a portfolio site for a friend which displays paintings. All paitings are displayed on the index page, and I've created a for loop so that click on each painting opens up modal displaying that painting:
// create references to the modal...
const modal = document.getElementById('myModal');
// to all images -- note I'm using a class!
const images = document.getElementsByClassName('myImages');
// the image in the modal
const modalImg = document.getElementById("img01");
// and the caption in the modal
const captionText = document.getElementById("caption");
// Go through all of the images with our custom class
for (let i = 0; i < images.length; i++) {
let img = images[i];
// and attach our click listener for this image.
img.addEventListener("click", openModal)
}
// Function to open modal
function openModal() {
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
I've attached previous and next buttons to the modal, and I'd like to be able to go back and forth between paintings once the modal is open:
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- The Close Button -->
<span class="close" onclick="document.getElementById('myModal').style.display='none'">×
</span>
<!-- Modal Content (The Image) -->
<img class="modal-content" id="img01">
<!-- Modal Caption (Image Text) -->
<div id="caption"></div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
I'm trying to add event listeners to the prev/next buttons however am running into trouble - I'm not sure how to access the selected image from the modal so it knows to open the previous/next one when prev/next buttons are clicked.
// selecting the prev and next buttons
const prev = document.querySelector(".prev")
const next = document.querySelector(".next")
prev.addEventListener("click", previousSlide);
function previousSlide() {
// Not sure what to put here...
}
Can anyone help me out or at least point me in the right direction? Thanks
Do be able to found the previous and/or next image you need to know on what image you are. I propose to do that by passing the index of the image to openModal and "saving" it using data-*.
Once this is done, when one click on .prev ou .next you only need to add or remove 1 to the index and call openModal
In the snippet below I've tried to "guess" what was the missing HTML and CSS
// create references to the modal...
const modal = document.getElementById('myModal');
// to all images -- note I'm using a class!
const images = document.getElementsByClassName('myImages');
// the image in the modal
const modalImg = document.getElementById("img01");
// and the caption in the modal
const captionText = document.getElementById("caption");
// Go through all of the images with our custom class
for (let i = 0; i < images.length; i++) {
let img = images[i];
// and attach our click listener for this image.
img.addEventListener("click", event => {
openModal(i)
});
}
// Function to open modal
function openModal(index) {
console.log('index', index);
modal.dataset.index = index;
modal.classList.add("open");
modalImg.src = images[index].src;
captionText.innerHTML = images[index].alt;
}
document.querySelector(".prev").addEventListener('click', event => {
const index = modal.dataset.index === '0' ? images.length - 1 : +modal.dataset.index - 1
openModal(index);
})
document.querySelector(".next").addEventListener('click', event => {
openModal((+modal.dataset.index + 1) % images.length);
})
#myModal {
display: none;
position: fixed;
top: 0;
left: 0;
backdrop-filter: blur(2px);
width: 100%;
height: 100%;
padding: 30px;
place-content: center;
box-sizing: border-box;
background-color: #e8e8e880;
}
#myModal.open {
display: grid;
}
.prev,
.next,
.close {
position: absolute;
cursor: pointer;
}
.close {
top: 20px;
right: 20px;
}
.prev,
.next {
top: 50%;
transform: translateY(-50%);
}
.prev {
left: 20px;
}
.next {
right: 20px;
}
<img src="https://picsum.photos/200/300?random=1" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=2" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=3" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=4" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=5" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=6" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=7" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=8" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=9" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=10" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=11" alt="" class="myImages">
<img src="https://picsum.photos/200/300?random=12" alt="" class="myImages">
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- The Close Button -->
<span class="close" onclick="document.getElementById('myModal').classList.remove('open')">×
</span>
<!-- Modal Content (The Image) -->
<img class="modal-content" id="img01">
<!-- Modal Caption (Image Text) -->
<div id="caption"></div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>

Animated gif alternative using jQuery to animate an image sequence

I put together this very simple jQuery code to animate a sequence of images. It works perfectly. you can view it here.
But now I am trying to update the code so it could work on multiple image sequences at once as long as it has its own class that is referenced in the jQuery code. So I updated it - view below. Unfortunately my updates are not working. Can you guys help me resolve this issue? Thank you in advance!
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let currentImg = 0;
function changeImg(allImg){
$(allImg[currentImg]).fadeOut(0, function(){
if(currentImg == allImg.length -1){
currentImg = 0;
}else {
currentImg++;
}
$(allImg[currentImg]).fadeIn(0)});
}
setInterval(changeImg(aniOne), 0050);
setInterval(changeImg(aniTwo), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>
As Chris G stated above:
The working code uses setInterval(changeImg, 50) which will work fine. The problem with your current attempt is setInterval(changeImg(aniOne), 50) which evaluates to a call to changeImg(aniOne), then a call to setInterval(undefined, 50) (since changeImg doesn't return anything). If you want this to work, you need to make changeImg into a function that returns a function. – Chris G
After we add these problems, we then have the issue of both animations sharing the currentImg variable, so instead I made two different variables and passed them along with the images. You can handle this many different ways.
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let num1 = 0;
let num2 = 0;
function changeImg(allImg, num){
function main(){
$(allImg[num]).fadeOut(0, function(){
if(num == allImg.length -1){
num = 0;
}else {
num++;
}
$(allImg[num]).fadeIn(0)});
}
return main;
}
setInterval(changeImg(aniOne, num1), 0050);
setInterval(changeImg(aniTwo, num2), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>

Why does my slider go blank after reaching the end?

I'm having a two issues/problems with the following slide.
It is a "double slider", so, two simultaneous slider in body section.
First is that when i reach the last image (9-nth, cos that much both sliders contain), the second slider continues to work properly (sliding images infinitely) but the first one just get blank.
Or if i click on previous button on begining then second doesn't work and images disapear, while the first one work nicely. Can't figure it out why. I've tried changing the "id" in the HTML and styling it but nothing change.
Second is, that i finally need to make it more dynamic, so, to avoid hardcoding images in the HTML and to putt them in JS and somehow append them in the DOM, but don't know what exactlly to do; creating an array, or using the "createElement"?
And which logic could be usable to actually include them in the DOM and have the following slider(s), considering the provided code?
Since it's my just second slider which i'm making, i found it pretty much hard, so any help/hint/advice is welcomed.
P.S Must be in jQuery and plugins excluded, so please don't provide any plugins links.
Thank you in advance.
var slides = $('.slide');
slides.first().before(slides.last());
$('button').on('click', function() {
// Selecting the slides
slides = $('.slide');
// Selecting button
var button = $(this);
// Register active slide
var activeSlide = $('.active');
// Next function
if (button.attr('id') == 'next') {
slides.last().after(slides.first());
activeSlide.removeClass('active').next('.slide').addClass('active');
}
// Previous function
if (button.attr('id') == 'previous') {
slides.first().before(slides.last());
activeSlide.removeClass('active').prev('.slide').addClass('active');
}
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.slider {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
}
.slide {
width: 100%;
height: 300px;
position: absolute;
transition: 0.6s ease;
transform: translate(-100%, 0);
}
.slide img {
width: 100%;
height: 300px;
}
.slide.active {
transform: translate(0, 0);
}
.slide.active~.slide {
transform: translate(100%, 0);
}
body {
text-align: center;
}
button {
margin-top: 20px;
border: none;
border-radius: 0;
background: aqua;
color: #333;
padding: 10px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slider">
<div class="slide active">
<img src="Assets/slider-image-1.jpg" alt="">
</div>
<div class="slide">
<img src="Assets/slider-image-2.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-3.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-4.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-5.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-6.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-7.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-8.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-9.jpg">
</div>
</div>
<div class="slider">
<div class="slide active">
<img src="Assets/slider-image-1.jpg" alt="">
</div>
<div class="slide">
<img src="Assets/slider-image-2.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-3.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-4.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-5.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-6.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-7.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-8.jpg">
</div>
<div class="slide">
<img src="Assets/slider-image-9.jpg">
</div>
</div>
<button id="previous"><img src="Assets/arrow-blue-left.png" alt=""></button>
<button id="next"><img src="Assets/arrow-blue-right.png" alt=""></button>
Your code doesn't work properly because the slides = $('.slide') variable contains all slides from both sliders. You have to manipulate the slides in the to sliders independently. The second failure is that in your example the first slide is the initial active slide. Only slides in range second -> penultimate are allowed. Working example here
function handleSlide(slider, direction) {
var slides = $(slider).find('.slide');
if(slides.length < 1) return;
// Register active slide
var activeSlide = $(slider).find('.active');
// Next function
if (direction == 'next') {
slides.last().after(slides.first());
activeSlide.removeClass('active').next('.slide').addClass('active');
}
// Previous function
if (direction == 'previous') {
slides.first().before(slides.last());
activeSlide.removeClass('active').prev('.slide').addClass('active');
}
}
$('button').on('click', function() {
var button = $(this);
handleSlide($("#slider1"), $(button).attr('id'));
handleSlide($("#slider2"), $(button).attr('id'));
});
Loading images dinamically: You can do that by defining an array which contains the images and you can append the images into the slider using the jQuery 'append' method. Working example on jsFiddle.
function fillSliders(slider, images) {
$(slider).empty();
for(var i = 0; i < images.length; i++) {
if(typeof images[i] == "string" && images[i] !== "") {
var active = (i == 1) ? " active" : "";
$(slider).append('<div class="slide'+active+'"><img src="'+images[i]+'"
alt="image-'+i+'" /></div>');
}
}
}
var images = ["image1.jpg", "image2.jpg","image3.jpg","image4.jpg"];
fillSliders($("#slider"), images);

How to change images on hover on and on with jQuery?

I've got such a problem:
inside my <div></div> there are always 5 images, only 1 is visible other 4 are hidden.
<style>
#id2, #id3, #id4, #id5 { display: none; }
</style>
<div>
<img id="id1" src='image.jpg'>
<img id="id2" src='image.jpg'>
<img id="id3" src='image.jpg'>
<img id="id4" src='image.jpg'>
<img id="id5" src='image.jpg'>
</div>
My aim is to change them in the constant time stamp (for example 1 second) on hover.
$('document').ready(function(){
$('#1').hover(function(){
// #id1 hide
// #id2 show
// #id2 hide
// #id3 show
// #id3 hide
// #id4 show
// #id4 hide
// #id5 show
// #id5 hide
// #id1 show
// and so on...
});
});
It's going to be used as a video preview, divs and inner images are going to be generated from MySQL DB.
Any help appreciated.
Here's a working example, based on what I understood from your question:
$('.preview').hover(function() {
var $that = $(this),
toggleFunction = function() {
var $visibleImg = $('img:visible', $that),
$nextImg = $visibleImg.next('img');
if(!$nextImg.length) {
$nextImg = $('img:first-child', $visibleImg.parent());
}
$nextImg.show().siblings().hide();
};
$that.data('interval', window.setInterval(toggleFunction, 1000));
toggleFunction();
}, function() {
window.clearInterval($(this).data('interval'));
});
.preview img {
display: none;
}
.preview img:first-child {
display: block;
}
.preview {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="preview">
<img src="https://s24.postimg.org/r74b0vcu9/frame_0.gif" />
<img src="https://s24.postimg.org/a7vclm1mp/frame_15.gif" />
<img src="https://s24.postimg.org/600kcv075/frame_30.gif" />
<img src="https://s24.postimg.org/7t82exarl/frame_45.gif" />
<img src="https://s24.postimg.org/5d6912sox/frame_60.gif" />
</div>

Categories

Resources