Creating a Slide Show with Javascript and HTML - javascript

I am very new to web development and am trying to create a slide show using JavaScript and HTML. The problem I keep running into is that when I FIRST load my page all the slide show text overlaps after that the slideshow runs as expected.
var current = 0;
var slides = document.getElementsByClassName("slide");
setInterval(function() {
for (var i = 0; i < slides.length; i++) {
slides[i].style.opacity = 0;
}
slides[current].style.opacity = 1;
current = (current != slides.length - 1) ? current + 1 : 0;
}, 2500);
.logo{
width:100px;
margin-left: 850px;
margin-top: -90px;
vertical-align:top;
}
.show {
position: absolute;width:500px; height:200px; left:50%; top:50%; margin-top: -140px;margin-left: -250px;
transition: opacity .5s ease-in;
}
.descrip {
text-align: center;
display: block;
position: absolute;width:500px; left:50%; top:50%; margin-top: 100px;margin-left: -250px;
transition: opacity .5s ease-in;
}
h1{
text-align: center;
margin-top: 130px;
}
<!DOCTYPE html>
<html>
<head>
<title>Tourism Slide Show</title>
<link href = "travelPics.css" rel = "stylesheet" type = "text/css">
<script type="text/javascript" src ="travelSlideShow.js"></script>
</head>
<body >
<h1>Uncle Phil's Tourism</h1>
<img src ='images/logo.jpg' class = "logo" alt = "logo">
<div class = "slide" >
<img src="images/athens.jpg" alt="Athens" class="show" >
<h2 class = "descrip">
Acropolis of Athens in Athens Greece <br>
The ruins of a 5th-century B.C temple.
</h2>
</div>
<div class = "slide">
<img src="images/burjkhalifa.jpg" alt="Burj Khalifa" class="show">
<h2 class = "descrip">The tallest structure in the world, standing at 829.8 m<br>Located in Dubai, United Arab Emirates</h2>
</div>
<div class = "slide">
<img src="images/cappadocia.jpg" alt="Cappadocia" class="show">
<h2 class = "descrip">
Located in central Turkey, is known for the Bronze Age homes carved into valley walls
</h2>
</div>
<div class = "slide">
<img src ="images/florence.jpg" alt ="Florence" class="show">
<h2 class = "descrip">
The Cathedral of Santa Maria del Fiore and Piazza Duomo <br>
Contains art and architecture by the greatest artists of the Italian Renaissance -- Ghiberti, Brunelleschi, Donatello, Giotto, and Michelangelo.
</h2>
</div>
<div class = "slide">
<img src = "images/lighthouse.jpg" alt ="Lighthouse" class="show">
<h2 class = "descrip"> Light house </h2>
</div>
<div class = "slide">
<img src = "images/louvre.jpg" alt = "Louvre" class="show">
<h2 class = "descrip"> Louvre</h2>
</div>
<div class = "slide">
<img src = "images/victoriafalls.jpg" alt = "Victoria Falls" class="show">
<h2 class = "descrip">Victoria falls </h2>
</div>
<div class = "slide">
<img src = "images/warmuseum.jpg" alt = "Canadian War Museum" class="show">
<h2 class = "descrip"> War Museum</h2>
</div>
</body>
</html>

Transform the first js part into the following:
//And manually call update once or at initial loading
//E.g. in jquery: $(document).on("load", update);
update();
setInterval(update, 2500);
function update()
{
for (var i = 0; i < slides.length; i++) {
slides[i].style.opacity = 0;
}
slides[current].style.opacity = 1;
current = (current != slides.length - 1) ? current + 1 : 0;
}
The reason for this is that setInterval will call the function after 2,5 seconds for the very first time. So you should manually call it initially.

Related

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 can I improve this simple image gallery code?

I'm trying to make a basic image gallery with simple html, css and js
This is the code so far.
$('.navigation-1').click(function() {
$('.cat-1').css("opacity", "1");
$('.cat-2').css("opacity", "0");
$('.cat-3').css("opacity", "0");
$('.cat-4').css("opacity", "0");
});
$('.navigation-2').click(function() {
$('.cat-1').css("opacity", "0");
$('.cat-2').css("opacity", "1");
$('.cat-3').css("opacity", "0");
$('.cat-4').css("opacity", "0");
});
$('.navigation-3').click(function() {
$('.cat-3').css("opacity", "1");
$('.cat-1').css("opacity", "0");
$('.cat-2').css("opacity", "0");
$('.cat-4').css("opacity", "0");
});
$('.navigation-4').click(function() {
$('.cat-4').css("opacity", "1");
$('.cat-1').css("opacity", "0");
$('.cat-2').css("opacity", "0");
$('.cat-3').css("opacity", "0");
});
.navigation {
margin-bottom: 15px;
}
.cat {
opacity: 0;
position: absolute;
transition: opacity 0.5s ease-in-out;
}
/* Show a picture at load */
.cat-1 {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="navigation">
<button class="nav navigation-1">Cat 1</button>
<button class="nav navigation-2">Cat 2</button>
<button class="nav navigation-3">Cat 3</button>
<button class="nav navigation-4">Cat 4</button>
</div>
<img class="cat cat-1" src="http://placekitten.com/300/200" alt="">
<img class="cat cat-2" src="http://placekitten.com/300/201" alt="">
<img class="cat cat-3" src="http://placekitten.com/301/200" alt="">
<img class="cat cat-4" src="http://placekitten.com/301/201" alt="">
How do I dynamically generate the buttons and hide the other images, when one image is shown.
I used opacity to show and hide images, but feel free to use whatever suits you best.
I'm sure the this keyword is useful here, but how?
How about the following... where I've added a "data-index" attribute to the "navigation" buttons.
The on button click you hide all "cat" items, and then show the required one by targeting it using the "data-index" attribute.
$('.nav').click(function() {
$('.cat').css("opacity", "0");
var id = $(this).data("index");
$('.cat-' + id).css("opacity", "1");
});
.navigation {
margin-bottom: 15px;
}
.cat {
opacity: 0;
position: absolute;
transition: opacity 0.5s ease-in-out;
}
/* Show a picture at load */
.cat-1 {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="navigation">
<button class="nav" data-index="1">Cat 1</button>
<button class="nav" data-index="2">Cat 2</button>
<button class="nav" data-index="3">Cat 3</button>
<button class="nav" data-index="4">Cat 4</button>
</div>
<img class="cat cat-1" src="http://placekitten.com/300/200" alt="">
<img class="cat cat-2" src="http://placekitten.com/300/201" alt="">
<img class="cat cat-3" src="http://placekitten.com/301/200" alt="">
<img class="cat cat-4" src="http://placekitten.com/301/201" alt="">
// get all cats
const cats = document.querySelectorAll('.cat')
// gets nav container
const nav = document.querySelector('.navigation')
// for each cat
for (let i = 0; i < cats.length; i++) {
// select current cat
const chosenCat = cats[i];
// create button for it
const button = document.createElement("button");
// add some text to button
button.innerHTML = `Cat ${i + 1}`;
// create onclick function that hides all cats and reveals current
button.onclick = () => {
// use Array.prototype.slice.call because you cant iterate the NodeList
Array.prototype.slice.call(cats).forEach(cat => cat.style.opacity = 0);
chosenCat.style.opacity = 1;
};
// add button to nav container
nav.appendChild(button);
}
// reveal initial cat
cats[0].style.opacity = 1;
.cat {
opacity: 0;
position: absolute;
transition: opacity 0.5s ease-in-out;
top: 0;
}
.navigation {
margin-top: 200px;
}
<img class="cat cat-1" src="http://placekitten.com/300/200" alt="">
<img class="cat cat-2" src="http://placekitten.com/300/201" alt="">
<img class="cat cat-3" src="http://placekitten.com/301/200" alt="">
<img class="cat cat-4" src="http://placekitten.com/301/201" alt="">
<div class="navigation">
</div>

slider.js for image rotation called from html rotates all images at the same time vs rotating through

I'm completing an assignment where we're supposed to have a site rotate through images. Here's the code from the home page:
<div id = "slideshow">
<div id = "slideshowWindow">
<div class = "slide"> <img src = "hotelroom1.jpg">
<div class = "slideText">
<h1 class = "slideHeading">Average Room</h1>
</div>
</div>
<div class = "slide" id = "slide2"> <img src = "hotelroom2.jpg">
<div class = "slideText">
<h1 class = "slideHeading">Luxury Room</h1>
</div>
</div>
<div class = "slide"> <img src = "hotelpool.jpg">
<div class slideText>
<h1 class = "slideHeading">Hote Pool Area</h1>
</div>
</div>
</div>
</div>
Toward the bottom are two script links:
<script src = "https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src = "slider.js"></script>
Which references the following slider.js file:
$(document).ready(function(){
//variables
var currentPosition = 0;
var slides = $('.slide');
var numberOfSlides = slides.length;
var speed = 3000;
var slideShowInterval = setInterval(changePosition, speed);
slides.wrapAll('<div id="dynamicWindow"></div>')
$('#dynamicWindow').css('width', '300%');
function changePosition() {
if (currentPosition == numberOfSlides - 1)
{currentPosition = 0;}
else { currentPosition++;}
moveSlide();
}
function moveSlide(){
jQuery('#dynamicWindow').animate({'marginLeft':(-currentPosition)*100+'%'});
}
});
Which is using the following CSS for formatting:
#slideshow #slideshowWindow {
position:relative;
overflow:hidden;
}
#slideshow #slideshowWindow .slide {
width:33.333333%;
float:left;
}
.slideText{
position:absolute;
top:100px;
padding-left:100px;
}
I am not a developer, just a student...please speak slowly and plainly!
Thanks,
Tom

How do I implement the scroll to top

I have written code with a click function. If the user clicks "next", set class "onscreen" to the next element.
What I want is the element that has class "onscreen" to scroll to top with animation duration of 1s.
This is my code:
HTML
<div class="slides">
<div class="slide onscreen" id="one">one</div>
<div class="slide" id="two">two</div>
<div class="slide" id="third">third</div>
<div class="slide" id="fourth">fourth</div>
</div>
<div class="buttons">
<button class="next" onclick="slide(this.className)">
Next slide
</button>
<button class="prev" onclick="slide(this.className)">
Previous slide
</button>
</div>
CSS
.buttons{
width:170px;
position:fixed;
top:10px;
left:50%;
margin-left:-85px;
}
.onscreen {
background-color: green;
}
Javascript
window.onload = function() {
var slide = document.getElementsByClassName("slide");
for (var i = 0; i < slide.length; i++) {
var heightslide = slide[i].offsetHeight;
}
console.log(heightslide);
}
var active = document.getElementsByClassName("onscreen");
function slide(prevnext) {
if (prevnext === "next") {
if (active[0].nextElementSibling) {
active[0].nextElementSibling.className = "slide onscreen";
active[0].className = "slide";
}
} else {
if (active[0].previousElementSibling) {
active[0].previousElementSibling.className = " slide onscreen ";
active[active.length - 1].className = "slide";
}
}
}
Hope somebody can help me with this.
Thanks a lot

simple jquery slideshow with navigation?

So I'm in the process of creating a pretty simple jQuery/CSS slideshow for a course of mine. It's about ten pages long, and right now it works fine if you want to just go from beginning to end in that order, but if you need to refresh the page for any reason, it sends you back to the first page. Since it's on the longer end, I'd like to be able to "click" to a certain page... is this possible without getting too complicated?
Here's my jQuery
function checkNav() {
if ($('.active-slide').hasClass('first')) {
$('.prev').hide();
$('.next').show();
} else if ($('.active-slide').hasClass('last')) {
$('.next').hide();
$('.prev').show();
} else {
$('.next').show();
$('.prev').show();
}
}
var main = function() {
checkNav();
$('.next').click(function() {
var currentSlide = $('.active-slide');
var nextSlide = currentSlide.next('.slide');
var currentDot = $('.active-dot');
var nextDot = currentDot.next();
//if nextslide is last slide, go back to the first
if (nextSlide.length === 0) {
nextSlide = $('.slide').first();
nextDot = $('.dot').first();
}
currentSlide.fadeOut(500).removeClass('active-slide');
nextSlide.fadeIn(1100).addClass('active-slide');
currentDot.removeClass('active-dot');
nextDot.addClass('active-dot');
checkNav();
});
//prev slide function
$('.prev').click(function() {
var currentSlide = $('.active-slide');
var prevSlide = currentSlide.prev('.slide');
var currentDot = $('.active-dot');
var prevDot = currentDot.prev();
//if prevslide is last slide, go back to the first
if (prevSlide.length === 0) {
prevSlide = $('.slide').last();
prevDot = $('.dot').last();
}
currentSlide.fadeOut(600).removeClass('active-slide');
prevSlide.fadeIn(600).addClass('active-slide');
currentDot.removeClass('active-dot');
prevDot.addClass('active-dot');
checkNav();
});
};
$(document).ready(main);
And here's a rough markup of what the HTML looks like
<div class="slide active-slide first">
<div class="content">
<p>First Slide</p>
</div>
</div>
<div class="slide">
<div class="content">
<p>second slide</p>
</div>
</div>
<div class="slide last">
<div class="content">
<p>third slide</p>
</div>
</div>
<div class="slider-nav">
<div class="prev">prev</div>
<ul class="dots">
<li class="dot active-dot">•</li>
<li class="dot">•</li>
<li class="dot">•</li>
</ul>
<div class="next">next</div>
</div>
Here's the jsFiddle ... I'd like to be able to click on one of the bullets and go to that corresponding slide....
$('ul.dots li').click(function(){
var num = $(this).index();
var currentSlide = $('.active-slide');
var nextSlide = $('.slide:eq('+num+')');
var currentDot = $('.active-dot');
var nextDot = $(this);
currentSlide.fadeOut(600).removeClass('active-slide');
nextSlide.fadeIn(600).addClass('active-slide');
currentDot.removeClass('active-dot');
nextDot.addClass('active-dot');
checkNav();
});
Add IDs to the divs. For instance:
<div class="slide active-slide first" id="1">
<div class="content">
<p>First Slide</p>
</div>
</div>
<div class="slide" id="2">
<div class="content" >
<p>second slide</p>
</div>
</div>
<div class="slide last" id="3">
<div class="content">
<p>third slide</p>
</div>
</div>
Then you can target specific slides using something like:
<ul class="dots">
<li class="dot active-dot"><a onclick="goto(1)">•</a></li>
<li class="dot"><a onclick="goto(2)">•</a></li>
<li class="dot"><a onclick="goto(3)">•</a></li>
</ul>
<script>
function goto(slide){
$(".slide").removeClass("active-slide");
$("#"+slide).addClass("active-slide");
$("#"+slide).show();
}
We need a way to "index" these items, I will do it by child so add a parent div class called slider:
<div id="slider">
...slides here...
</div>
You need to use localStorage (used to save data between pages) to keep track of both what slide you are on and what dot you are on in the nav bar. This can save data even when we leave the page (when it refreshes), making it so we still know our last page we where on. I will use this to keep track of the current index of each slide. So when the page loads we need to check that if our localStorage item exist:
// If we have saved data add it's index to active-slide
if(localStorage.getItem("activeSlide")) {
$("#slider div.slide")
.eq(localStorage.getItem("activeSlide"))
.addClass("active-slide");
$('.dots li.dot')
.eq(localStorage.getItem("activeSlide"))
.addClass("active-dot");
} else { // Otherwise make them both 0
$("#slider div.slide")
.eq('0')
.addClass("active-slide");
$('.dots li.dot')
.eq('0')
.addClass("active-dot");
}
Then when we move to the next slide next or the last slide prev we update the localStorage item to the current index of the item in active-slide:
// Make the current index of the item in active slide our updated variable
localStorage.setItem( "activeSlide",
$("#slider div.slide").index($(".active-slide")) );
Here is a working example
This way when the page refreshes we stay on the last slide we where looking at before.
<!doctype html>
<html>
<head>
<style>
body{
text-align: center;
}
#slideshow{
margin:0 auto;
width:600px;
height:450px;
overflow: hidden;
position: relative;
}
#slideshow ul{
list-style: none;
margin:0;
padding:0;
position: absolute;
}
#slideshow li{
float:left;
}
#slideshow a:hover{
background: rgba(0,0,0,0.8);
border-color: #000;
}
#slideshow a:active{
background: #990;
}
.slideshow-prev, .slideshow-next{
position: absolute;
top:180px;
font-size: 30px;
text-decoration: none;
color:#fff;
background: rgba(0,0,0,0.5);
padding: 5px;
z-index:2;
}
.slideshow-prev{
left:0px;
border-left: 3px solid #fff;
}
.slideshow-next{
right:0px;
border-right: 3px solid #fff;
}
</style>
</head>
<body>
<div id="slideshow">
«
<ul>
<li><img src="1.jpg" alt="photo1" /></li>
<li><img src="2.jpg" alt="photo2" /></li>
<li><img src="3.jpg" alt="photo3" /></li>
<li><img src="4.jpg" alt="photo4" /></li>
</ul>
»
</div>
<!--
We use Google's CDN to serve the jQuery js libs.
To speed up the page load we put these scripts at the bottom of the page
-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
//an image width in pixels
var imageWidth = 600;
//DOM and all content is loaded
$(window).ready(function() {
var currentImage = 0;
//set image count
var allImages = $('#slideshow li img').length;
//setup slideshow frame width
$('#slideshow ul').width(allImages*imageWidth);
//attach click event to slideshow buttons
$('.slideshow-next').click(function(){
//increase image counter
currentImage++;
//if we are at the end let set it to 0
if(currentImage>=allImages) currentImage = 0;
//calcualte and set position
setFramePosition(currentImage);
});
$('.slideshow-prev').click(function(){
//decrease image counter
currentImage--;
//if we are at the end let set it to 0
if(currentImage<0) currentImage = allImages-1;
//calcualte and set position
setFramePosition(currentImage);
});
});
//calculate the slideshow frame position and animate it to the new position
function setFramePosition(pos){
//calculate position
var px = imageWidth*pos*-1;
//set ul left position
$('#slideshow ul').animate({
left: px
}, 300);
}
</script>
</body>
</html>

Categories

Resources