I asked this question before, and the answers I received didn't work for me.
I have an HTML site with a selection of around 50 pictures. When clicking on one of them, a modal site opens with a slideshow (big one on top, small samples beneath it). I wish to add to the JS code that after selecting one of the small samples the window automatically jumps to the top of the page where the sample is shown in bigger size.
Here's my JS code:
<script>
function openModal() {
document.getElementById('myModal').style.display = "block";
}
function closeModal() {
document.getElementById('myModal').style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>
I already tried to add window.scrollTo(0, 0); to the currentSlide(n) function, and just scroll(0,0), but it didn't work.
Here's where the onclick="currentSlide" is. I got this code from somewhere online.
<div class="column"><img class="demo" src="img/gallery/img55.jpg" onclick="currentSlide(55)" alt="Sample 55"></div>
</div> <!-- end div modal_samples -->
</div> <!-- end div modal content -->
Please let me know if you need me to provide something else.
I am not certain how far along you are with the functionality, but you could use something like: "window.location.hash = null; window.location.hash='(the id attribute value of the large image)';" in an existing or new function.
So, basically:
// Reset from any previous setting
window.location.hash = null;
// Set the new SRC for the IMG element containing the large image (at top of page)
largeImageElement.src = (URL to Image OR same as thumbnail image SRC);
// Move to where the large image (IMG) resides on page
window.location.hash = largeImageElement.id;
Let me know if you don't understand.
Related
I am working on a slideshow / carousel in HTML with vanilla JS controlling the changing of the slides. I am happy with the current functionality, but I would like the slideshow to pause if the user hovers over the gallery. I understand that I could do this by clearing the timeout function, but I am stuck on how to integrate that into the current function. I am trying to add this functionality to the 'showSlides' function.
HTML
<div class="galleryImages">
<div class="numbertext">1 / 2</div>
<img src="./assets/images/1.jpg" style="width: 100%;" />
</div>
<div class="galleryImages">
<div class="numbertext">2 / 2</div>
<img src="./assets/images/2.jpg" style="width: 100%;" />
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
JS
var slideIndex = 0;
showSlides();
// Next/previous controls
function plusSlides(n) {
changeSlides((slideIndex += n));
}
// automatically show slides and change the slide at the set timeout
function showSlides() {
var i;
var slides = document.getElementsByClassName("galleryImages");
let gallery = document.getElementById("gallery");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {
slideIndex = 1;
}
slides[slideIndex - 1].style.display = "block";
setTimeout(showSlides, 5000); // Change image every 5 seconds
}
// change the slides based on the user input on the prev and next buttons
function changeSlides(n) {
var i;
var slides = document.getElementsByClassName("galleryImages");
if (n > slides.length) {
slideIndex = 1;
}
if (n < 1) {
slideIndex = slides.length;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
Add a variable which will hold a reference to the timeout to the top:
var currentTimeout = null;
Store the new timeout into this variable when creating:
currentTimeout = setTimeout(showSlides, 5000); // Change image every 5 seconds
Hover event handler:
if (currentTimeout) {
clearTimeout(currentTimeout);
currentTimeout = null;
}
Hoverout event handler:
if (currentTimeout) {
// Should never happen, but to be safe...
clearTimeout(currentTimeout);
}
currentTimeout = setTimeout(showSlides, 5000); // Change image every 5 seconds
In showSlides() set
gallery.addEventListener('mouseover', function() {
// stop timeout here
});
gallery.addEventListener('mouseout', function() {
// restart automatic slides change
});
EDIT: as showSlides() is executed many times you'll need to remove event listeners, or refactor your code, so that those listeners are set once at the beginning only.
Are you able explain this simple image slider code line by line?
I'm particularly interested in where the n and no values come from in currentSlide(no) + plusSlides(n).
var slideIndex = 0;
var slides = document.getElementsByClassName("mySlides");
var interval;
var pauseButton = document.getElementById("pause");
showSlides();
playSlideshow();
function showSlides() {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {
slideIndex = 1;
}
slides[slideIndex - 1].style.display = "block";
}
// Manual control
function currentSlide(no) {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex = no;
slides[no - 1].style.display = "block";
}
function plusSlides(n) {
var newslideIndex = slideIndex + n;
if (newslideIndex < 6 && newslideIndex > 0) {
currentSlide(newslideIndex);
}
}
Edited to add rest of the code.
// Pause
var playing = true;
function pauseSlideshow() {
var pauseButton = document.getElementById("pause");
pauseButton.innerHTML = "▸";
playing = false;
clearInterval(interval);
}
function playSlideshow() {
pauseButton.innerHTML = "⏸";
playing = true;
interval = setInterval(showSlides, 5000);
}
pauseButton.onclick = function () {
if (playing) {
pauseSlideshow();
} else {
playSlideshow();
}
};
As per the comments, I have added additional code.
Yes, can do!
The first function showSlides is called. It first makes every element with the mySlides class invisible (basically hides all your slides). Then it increments the slide index and checks to see if the index is over the total amount of slides so it can start from the beginning again. Finally it shows the slide that the index is referring to.
The currentSlide function sets the active slide to the index provided in the no argument. First it hides all the slides and then sets the new slide index to what no is and then shows that slide.
Finally plusSlides goes forward (or backwards if using a negative number) n slides. The if statement checks if the index is between 1 and 5. If it is the slide that corresponds with the new index is shown.
A few notes
for loops can be written without a variable declaration preceding it like this
for(let x = 0; x < 100; x++){
console.log(x);
}
In your plusSides function, you check for a specific range, but you could base it off of the amount of slides with slides.length like in showSlides. Also, I would recommend making sure that if the index does happen to fall out of this range to set the index to a default value.
if (newslideIndex < slides.length && newslideIndex > 0) {
currentSlide(newslideIndex);
} else {
currentSlide(1);
}
That is all!
Working on building a library, trying to put in a fading image slider, it shows the first image, but then when it tries to change I get TypeError: document.querySelector(...) is null. Any help would be great!
export let styl = (function() {
let slideIndex = 0;
return {
simpleSlideShow: function() {
//automatic Slider
let i;
let slides = document.getElementsByClassName("mySlides");
console.log("Image change");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {
slideIndex = 1;
}
slides[slideIndex - 1].style.display = "block";
},
slideShowImageSetup: function(timeDelay, id, images) {
//Building HTML with given array of images
let i;
for (i = 0; i < images.length; i++) {
let elem = document.createElement("img");
elem.setAttribute("alt", "image");
elem.setAttribute("src", images[i]);
elem.setAttribute("class", "mySlides");
document.querySelector(id).appendChild(elem);
}
setTimeout(styl.simpleSlideShow, 1);
setInterval(styl.simpleSlideShow, timeDelay);
return 1;
},
fadingSlideShow: function(id, images) {
document.querySelector(id).className += "fadeOut";
setTimeout(function() {
document.querySelector(id).src = images[slideIndex];
document.querySelector(id).className = "";
slideIndex++;
if (slideIndex == images.length) {
slideIndex = 0;
}
setTimeout(styl.fadingSlideShow(id, images), 3000);
}, 1000);
},
};
})();
Where I'm calling the function
let images = [
"https://cdn141.picsart.com/297231911148201.jpg?c256x256",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQIfOEjoaYJNDHGmdgRa8EQp50VCicpK0R_0QpZLftE2zzgJky"
];
styl.fadingSlideShow("#slider", images);
<img id="slider"></img>
css that makes the fade effect
#slider {
opacity: 1;
transition: opacity 3s;
}
#slider.fadeOut {
opacity: 0;
}
Your second setTimeout is not sending in the id or images to styl.fadingSlideShow.
setTimeout(function(){styl.fadingSlideShow(id, images)}, 3000);
Also, put the second setTimeout inside the first one.
I am having trouble with my JavaScript file. Specifically for my Modal Slides and Individual Image Modal sections, I can get them to work when I add them as a tag in the HTML, but they do not work when I add them in the js file. Basically, I am trying to create this: https://www.w3schools.com/howto/howto_js_lightbox.asp, but without the pictures on the bottom. I feel like I'm halfway there, but didn't adjust everything correctly.
I've tried searching on Stack Overflow for an answer, but was unable to find one, so I apologize if this is a duplicate. Any help is much appreciated.
Here is the bottom of my HTML:
<!-- ============================= -->
<!-- All your JavaScript comes now -->
<!-- ============================= -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Bootstrap core JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Can place script tags with JavaScript files here -->
<script src="js/jquery.stellar.min.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>
Here is my js file:
$(document).ready(function(){
//Slideshow Speed
$('.carousel').carousel({
interval: 8000
});
//Smooth Scrolling
var $root = $('html, body');
$('.navbar-nav a').click(function() {
var href = $.attr(this, 'href');
$root.animate({
scrollTop: $(href).offset().top
}, 500, function () {
window.location.hash = href;
});
return false;
});
//Collapse Navbar
$(document).ready(function () {
$(".navbar-nav li a").click(function(event) {
$(".navbar-collapse").collapse('hide');
});
});
// Stellar
$(window).stellar();
// Tooltips
$(function () {
$('#item1').tooltip();
});
$(function () {
$('[data-toggle="tooltip"]').tooltip();
});
//Modal Slides
function openModal() {
document.getElementById('our-adventures-modal').style.display = "block";
}
function closeModal() {
document.getElementById('our-adventures-modal').style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
//Individual Image Modal
var modal = document.getElementById('myModal');
var img = $('.myImg');
var modalImg = $("#img01");
var captionText = document.getElementById("caption");
$('.myImg').click(function(){
modal.style.display = "block";
var newSrc = this.src;
modalImg.attr('src', newSrc);
captionText.innerHTML = this.alt;
});
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
});
I am trying to make the slides fade in and out instead of display none/block using JS. Is this going to need to be done using css or can i do it just in JS. Thanks
code:
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentDot(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
console.log('SHOWSLIDES');
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("nav-dot");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
}
or would it be better converting this to jquery and using .fadeOut() / .fadeIn()
Before: Just look a little bit into it source of jQuery:
.fadeIn()
http://james.padolsey.com/jquery/#v=1.11.2&fn=fadeIn
.animation()
http://james.padolsey.com/jquery/#v=1.11.2&fn=animate
Here is an approach how you could possibly do it:
var fadeInBtn = document.getElementById('fadeIn');
fadeInBtn.addEventListener('click', function() {
var testString = document.getElementById('test');
fadeIn(testString, 30);
});
var fadeOutBtn = document.getElementById('fadeOut');
fadeOutBtn.addEventListener('click', function() {
var testString = document.getElementById('test');
fadeOut(testString, 60);
});
function fadeIn(element, speed) {
var interval = setInterval(function () {
var opacity = parseFloat(element.style.opacity);
if(opacity >= 1.0) {
clearInterval(interval);
}
element.style.opacity = opacity + 0.1;
}, speed);
};
function fadeOut(element, speed) {
var interval = setInterval(function () {
var opacity = parseFloat(element.style.opacity);
if(opacity <= 0) {
clearInterval(interval);
}
element.style.opacity = opacity - 0.1;
}, speed);
}
div {
font-size: 300%;
}
<button id="fadeIn">Test .fadeIn()</button>
<button id="fadeOut">Test .fadeOut()</button>
<div id="test" style="opacity: 0">Example String</div>
Another solution is to use CSS(3) for this. I reference this already asked question here: Using CSS for fade-in effect on page load