I'm trying to make an image gallery with HTML, CSS and JS. The CSS works but there is a problem with the JS. I've made it so you can either click on an image or click on a button to see all of the images in order. But if I click on the third or fourth image and click the L button (stands for LEFT) it jumps from that image to the first image. For some reason it just doesn't want to show the second image.
I've been trying to fix this for hours and it still doesn't work as it should.
var num = 0;
function elementID(indexes) {
var index = $(".images").index(indexes);
var num = index;
}
function myFunction(imgs) {
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = imgs.src;
expandImg.parentElement.style.display = "block";
}
function right() {
if (num >= document.getElementsByClassName('images').length - 1) {
num = document.getElementsByClassName('images').length - 1;
} else {
num++;
}
var expandImg2 = document.getElementById("expandedImg");
var image = document.getElementsByClassName('images')[num];
expandImg2.src = image.src;
}
function left() {
if (num <= 0) {
num++;
return false;
} else {
num--;
}
var expandImg2 = document.getElementById("expandedImg");
var image = document.getElementsByClassName('images')[num];
expandImg2.src = image.src;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="text-align:center">
<h2>Tabbed Image Gallery</h2>
<p><a onclick="left();" id="left">L</a> | <a onclick="right();" id="right">R</a>
</div>
<!-- The four columns -->
<div class="row">
<div class="column">
<img src="https://www.w3schools.com/howto/img_nature.jpg" alt="Nature" style="width:100%" class="images" onclick="myFunction(this);elementID(this);">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_snow.jpg" alt="Snow" style="width:100%" class="images" onclick="myFunction(this);elementID(this);">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_mountains.jpg" alt="Mountains" style="width:100%" class="images" onclick="myFunction(this);elementID(this);">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_lights.jpg" alt="Lights" style="width:100%" class="images" onclick="myFunction(this);elementID(this);">
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
Try this solution using the next() and prev() from jQuery.
var currentEl; // track current el
$(document).ready(() => {
$('.column').on('click', function() { // bind clicks
currentEl = this;
addImage($(this).find('img'));
});
$('.closebtn').on('click', function() { // bind clicks to close button
currentEl = undefined; // either you can do this to reset the flow, or comment to maintain the flow
});
});
function addImage(img) {
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = img[0].src;
expandImg.parentElement.style.display = "block";
}
function right() { // jump to next
var next = currentEl ? $(currentEl).next() : $('.column').first();
if (next.length > 0) {
addImage($(next).find('img'));
currentEl = next;
}
}
function left() { // jump to prev
var prev = currentEl ? $(currentEl).prev() : $('.column').first();
if (prev.length > 0) {
addImage($(prev).find('img'));
currentEl = prev;
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="text-align:center">
<h2>Tabbed Image Gallery</h2>
<p><a onclick="left();" id="left">L</a> | <a onclick="right();" id="right">R</a>
</div>
<!-- The four columns -->
<div class="row">
<div class="column">
<img src="https://www.w3schools.com/howto/img_nature.jpg" alt="Nature" style="width:100%" class="images">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_snow.jpg" alt="Snow" style="width:100%" class="images">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_mountains.jpg" alt="Mountains" style="width:100%" class="images">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_lights.jpg" alt="Lights" style="width:100%" class="images">
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
Related
I am currently creating a horizontal image slider which will be used more than once with different amount of images.
At the moment, the parent div needs to be bigger than 100% to fit all images in, so I calculate the width by adding all widths of the child divs (which include the images) manually in a calculator and then add it to the css, but I want to be able to calculate it automatically with the help of either CSS or JS/jQuery.
window.onload = function(){
let images = [...document.querySelectorAll('.bild')];
let slider = document.querySelector('.slider');
let sliderWidth;
let imageWidth;
let current = 0;
let target = 0;
let ease = .05;
window.addEventListener('resize', init);
function lerp(start, end, t){
return start * (1-t) + end * t;
}
function setTransform (el, transform){
el.style.transform = transform;
}
function init(){
sliderWidth = slider.getBoundingClientRect().width;
imageWidth = sliderWidth / images.length;
document.body.style.height = `${sliderWidth - (window.innerWidth - window.innerHeight)}px`
}
function animate(){
current = parseFloat(lerp(current, target, ease)).toFixed(2);
target = window.scrollY;
setTransform(slider, `translateX(-${current}px)`);
requestAnimationFrame(animate);
}
init();
animate();
console.log(sliderWidth)
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
.slider {
position: absolute;
top: 0;
left: 0;
width: 3900px; /* this should be calculated automatically by the amount of divs with the class "item" multiplied by the item width */
height: 100%;
}
.slider-inner {
position: absolute;
top: 5%;
height: 90%;
display: flex;
justify-content: space-around;
}
.item {
position: relative;
width: 455px;
height: 100%;
overflow: hidden;
z-index: 1;
background: #13271b;
}
.image {
position: absolute;
width: 435px;
height: 100%;
background-size: cover;
background-position: top center;
border: none;
}
/* example "images" */
#one, #four {
background-color: #aaaaaa;
}
#two, #five {
background-color: #222222;
}
#three, #six {
background-color: #777777;;
}
#zero {
background-color: #ee2277;;
}
<div class="container">
<div class="slider">
<div class="slider-inner">
<div class="item">
<div class="image" id="zero">
</div>
</div>
<div class="item">
<div class="image" id="one">
</div>
</div>
<div class="item" >
<div class="image" id="two">
</div>
</div>
<div class="item">
<div class="image" id="three">
</div>
</div>
<div class="item">
<div class="image" id="four">
</div>
</div>
<div class="item">
<div class="image" id="five">
</div>
</div>
<div class="item">
<div class="image" id="six">
</div>
</div>
</div>
</div>
</div>
Try something like this:
/** #param {HTMLElement} sliderEl */
function scaleSlider(sliderEl) {
let totalWidth = 0;
sliderEl.querySelectorAll(".item").forEach(item => totalWidth += item.getBoundingClientRect().width);
sliderEl.style.width = `${totalWidth}px`;
}
I am a beginner and want to know how to change the shape of the arrows from my carousel to look like the arrows from the w3schools example. How do I change it to that type of arrow, instead of a triangular arrow?
And if its change how do I also change the size of the arrow?
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
//Clear all images
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = "none";
}
}
// initialize slider
function startSlide() {
reset();
sliderImages[0].style.display = "block";
}
//show previous
function slideLeft() {
reset();
sliderImages[current - 1].style.display = "block";
current--;
}
//show next
function slideRight() {
reset();
sliderImages[current + 1].style.display = "block";
current++;
}
//left arrow click
arrowLeft.addEventListener("click", function () {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
});
//right arrow click
arrowRight.addEventListener("click", function () {
if (current === sliderImages.length - 1) {
current = -1;
}
slideRight();
});
startSlide();
#slider,
.wrap,
.slide-content {
max-width: 1000px;
position: relative;
margin: auto;
}
.wrap {
position: relative;
}
.slide-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.arrow {
cursor: pointer;
position: absolute;
top: 46%;
width: 0;
height: 0;
border-style: solid;
z-index: 1;
}
#arrow-left {
border-width: 30px 40px 30px 0;
border-color: transparent #cccccc transparent transparent;
left: 0;
}
#arrow-right {
border-width: 30px 0px 30px 40px;
border-color: transparent transparent transparent #cccccc;
right: 0;
}
/* Caption text */
.text {
position: relative;
color: #212529;
font-size: 18px;
top: 28px;
width: 100%;
text-align: center;
font-family: "Roboto Condensed", sans-serif;
font-weight: 400;
}
<main class="main">
<div class="wrap">
<div id="arrow-left" class="arrow"></div>
<div id="arrow-right" class="arrow"></div>
<div id="slider">
<div class="slide slide1">
<div class="slide-content">
<div id="container">
<img class="background-image" src="image1" alt="">
</div>
<div class="text">image1</div>
</div>
</div>
<div class="slide slide1">
<div class="slide-content">
<div id="container">
<img class="background-image" src="image2" alt="">
</div>
<div class="text">image2</div>
</div>
</div>
</div>
</div>
</main>
W3Schools is using ❯ for ❯ and ❮ for ❮. These are Unicode characters.
Since they are rendered as text you can size them with CSS font-size
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
//Clear all images
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = "none";
}
}
// initialize slider
function startSlide() {
reset();
sliderImages[0].style.display = "block";
}
//show previous
function slideLeft() {
reset();
sliderImages[current - 1].style.display = "block";
current--;
}
//show next
function slideRight() {
reset();
sliderImages[current + 1].style.display = "block";
current++;
}
//left arrow click
arrowLeft.addEventListener("click", function () {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
});
//right arrow click
arrowRight.addEventListener("click", function () {
if (current === sliderImages.length - 1) {
current = -1;
}
slideRight();
});
startSlide();
#slider,
.wrap,
.slide-content {
max-width: 1000px;
position: relative;
margin: auto;
}
.wrap {
position: relative;
}
.slide-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.arrow {
cursor: pointer;
position: absolute;
top: 46%;
width: 30px; /* For your example code, make this match the font-size */
height: 30px; /* For your example code, make this match the font-size */
border-style: none;
z-index: 1;
font-size:30px; /* Change the arrow size here */
}
#arrow-left {
left: 0;
}
#arrow-right {
right: 0;
}
/* Caption text */
.text {
position: relative;
color: #212529;
font-size: 18px;
top: 28px;
width: 100%;
text-align: center;
font-family: "Roboto Condensed", sans-serif;
font-weight: 400;
}
<main class="main">
<div class="wrap">
<div id="arrow-left" class="arrow">❮</div>
<div id="arrow-right" class="arrow">❯</div>
<div id="slider">
<div class="slide slide1">
<div class="slide-content">
<div id="container">
<img class="background-image" src="image1" alt="">
</div>
<div class="text">image1</div>
</div>
</div>
<div class="slide slide1">
<div class="slide-content">
<div id="container">
<img class="background-image" src="image2" alt="">
</div>
<div class="text">image2</div>
</div>
</div>
</div>
</div>
</main>
W3Schools has used html symboles utf8 dingbats ❮ and ❯ inside links. If you want to change them you should use other codes from the table. You can change their size by changing their parent font size; in your case a tag.
I built a JS slideshow with clickable indicators. I would like for my slideshow to play automatically, while maintaining the functionality of the indicator buttons.
In the code example below, I attempted to add a setTimeout() method to change the image every 2000ms, but it seems to not be working. What would be the best approach to change the JS so I have some automation? I also attempted to use the setInterval method with no luck. I will provide the code below:
Thank you in advance for the help/tips/and advice
var editorialSlideIndex = 1;
showEditorialSlides(editorialSlideIndex);
//Next/previous controls
function plusSlides(n) {
showEditorialSlides(editorialSlideIndex += n);
}
//Thumbnail image controls
function currentSlide(n) {
showEditorialSlides(editorialSlideIndex = n);
}
function showEditorialSlides(n) {
var i;
var slides = document.getElementsByClassName("editorial-slideshow");
var slideDotInd = document.getElementsByClassName("slideDotInd");
if (n > slides.length) {
editorialSlideIndex = 1
}
if (n < 1) {
editorialSlideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < slideDotInd.length; i++) {
slideDotInd[i].className = slideDotInd[i].className.replace(" active-slider", "");
}
slides[editorialSlideIndex - 1].style.display = "block";
slideDotInd[editorialSlideIndex - 1].className += " active-slider";
setTimeout(showEditorialSlides, 2000); // Change image every 2 seconds
}
/*Slideshow Container */
.editorial-slideshow-container {
padding-top: 15px;
position: relative;
margin: auto;
}
/*Default Hide Images*/
.editorial-slideshow {
display: none;
}
/*Next and previous buttons*/
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -34px;
padding: 10px;
color: white;
font-weight: bold;
font-size: 34px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
background-color: rgba(0, 128, 115, .5);
}
/* Position "next button" */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, background color */
.prev:hover,
.next:hover {
background-color: rgba(0, 128, 115, .8);
}
/* Caption text
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
Number text (1/3 etc)
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 15;
}
*/
/* The slideslideDotInd/bullets/indicators */
.slideDotInd {
cursor: pointer;
height: 15px;
width: 15px;
margin: 15px 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active-slider,
.slideDotInd:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: .25s;
}
#-webkit-keyframes fade {
from {
opacity: .8
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .8
}
to {
opacity: 1
}
}
#media only screen and (max-width: 425px) {
#CGConainer .banner-title H1 {
line-height: 50px;
}
}
#media only screen and (min-width: 768px) {
.editorial-slideshow-container {
width: 75%;
/*Max width is 576px*/
}
}
#media only screen and (min-width: 1024px) {
.editorial-slideshow-container {
width: 50%;
}
}
<div class="editorial-slideshow-container">
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-1.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-2.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-3.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-4a.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-5a.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-6.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-7.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-8.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-9.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-10.jpg" style="width:100%">
</div>
<p class="prev" onclick="plusSlides(-1)">‹</p>
<p class="next" onclick="plusSlides(1)">›</p>
</div>
<div style="text-align:center">
<span class="slideDotInd" onclick="currentSlide(1)"></span>
<span class="slideDotInd" onclick="currentSlide(2)"></span>
<span class="slideDotInd" onclick="currentSlide(3)"></span>
<span class="slideDotInd" onclick="currentSlide(4)"></span>
<span class="slideDotInd" onclick="currentSlide(5)"></span>
<span class="slideDotInd" onclick="currentSlide(6)"></span>
<span class="slideDotInd" onclick="currentSlide(7)"></span>
<span class="slideDotInd" onclick="currentSlide(8)"></span>
<span class="slideDotInd" onclick="currentSlide(9)"></span>
<span class="slideDotInd" onclick="currentSlide(10)"></span>
</div>
It's such a small change.
The way you called setTimeout is wrong.
function showEditorialSlides(n) {
var i;
var slides = document.getElementsByClassName("editorial-slideshow");
var slideDotInd = document.getElementsByClassName("slideDotInd");
if (n > slides.length) {
editorialSlideIndex = 1
}
if (n < 1) {
editorialSlideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < slideDotInd.length; i++) {
slideDotInd[i].className = slideDotInd[i].className.replace(" active-slider", "");
}
slides[editorialSlideIndex - 1].style.display = "block";
slideDotInd[editorialSlideIndex - 1].className += " active-slider";
setTimeout(() => showEditorialSlides(editorialSlideIndex = (n+1)), 2000); // Change image every 2 seconds
}
And that was the reason your function was being called incorrectly.
EDIT: I forgot to mention the reason. There was no way JavaScript knew what parameters you were passing to the function when you're trying to recurse.
You can try it out in the fiddle
Would you anyone please help resolve this conflict? I would really appreciate that.
I am trying to use two javascripts of Slider and Light Box from w3schools.com on one HTML page but, I guess, both javascripts use the same names(or values) for each function so when I use them in one page at the same time, they don't work. but when I remove one set of css/html/javascript for each slider or light box, either works well.
Please help this for me.
Thank you very much in advance.
CSS
<style>
body {
font-family: Verdana, sans-serif;
margin: 0;
}
/* --------- Slider ---------- */
* {box-sizing:border-box}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor:pointer;
height: 13px;
width: 13px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
/* ----- Light Box -------*/
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: transparent;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
border: none;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
.mySlides {
display: none;
}
.cursor {
cursor: pointer
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
img {
margin-bottom: -4px;
}
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1;
}
img.hover-shadow {
transition: 0.3s
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)
}
.container {margin: 0 auto; max-width: 1000px;}
</style>
HTML
<body>
<div class="container">
<!-- ================ Slideshow ================ -->
<div class="slideshow-container mt20 mb10">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="https://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<div style="text-align:center;margin-top:10px;">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div> <!-- // Slider -->
<!-- Lightbox -->
<h2 style="text-align:center">Lightbox</h2>
<div class="row">
<div class="column">
<img src="https://www.w3schools.com/howto/img_nature.jpg" style="width:100%" onclick="openModal();currentSlide(1)" class="hover-shadow cursor">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_fjords.jpg" style="width:100%" onclick="openModal();currentSlide(2)" class="hover-shadow cursor">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_mountains.jpg" style="width:100%" onclick="openModal();currentSlide(3)" class="hover-shadow cursor">
</div>
<div class="column">
<img src="https://www.w3schools.com/howto/img_lights.jpg" style="width:100%" onclick="openModal();currentSlide(4)" class="hover-shadow cursor">
</div>
</div>
<div id="myLightBox" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<div class="LB-Slides">
<div class="numbertext">1 / 4</div>
<img src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
</div>
<div class="LB-Slides">
<div class="numbertext">2 / 4</div>
<img src="https://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%">
</div>
<div class="LB-Slides">
<div class="numbertext">3 / 4</div>
<img src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
</div>
<div class="LB-Slides">
<div class="numbertext">4 / 4</div>
<img src="https://www.w3schools.com/howto/img_lights_wide.jpg" style="width:100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
<div class="column">
<img class="demo cursor" src="https://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%" onclick="currentSlide(1)" alt="Nature and sunrise">
</div>
<div class="column">
<img class="demo cursor" src="https://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%" onclick="currentSlide(2)" alt="Trolltunga, Norway">
</div>
<div class="column">
<img class="demo cursor" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
</div>
<div class="column">
<img class="demo cursor" src="https://www.w3schools.com/howto/img_lights_wide.jpg" style="width:100%" onclick="currentSlide(4)" alt="Northern Lights">
</div>
</div>
</div>
</div><!-- // Lightbox -->
</div>
Javascript
<script>
/* --------- Slider ---------- */
var slideIndex = 1;
showSlides(slideIndex);
setInterval(function(){ showSlides(++slideIndex); }, 4000);
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("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";
}
/* --------- LightBox ---------- */
function openModal() {
document.getElementById('myLightBox').style.display = "block";
}
function closeModal() {
document.getElementById('myLightBox').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("LB-Slides");
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;
}
/* --------- //LightBox ---------- */
</script>
</body>
First of all – yes, you are right, both of your scripts are conflicting to each other due the same methods names. Since it's written in global scope (window) you basically override each other functionality.
You could try to use JavaScript module pattern to isolate scope of each of your "widgets", even if you gonna use the same methods names, your code will be executed in it's own scope.
As quick example how to rewrite this into modules:
http://jsbin.com/pipajawiwa/1/edit?html,js,output
/* --------- Slider ---------- */
var slider = (function() {
var slider = {};
slider.setIntervals = function() {
setInterval(function() {
slider.showSlides(++slider.slideIndex);
}, 4000);
};
slider.plusSlides = function(n) {
slider.showSlides(slider.slideIndex += n);
};
slider.currentSlide = function(n) {
slider.showSlides(slider.slideIndex = n);
};
slider.showSlides = function(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {
slider.slideIndex = 1
}
if (n < 1) {
slider.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[slider.slideIndex - 1].style.display = "block";
dots[slider.slideIndex - 1].className += " active";
};
slider.init = function() {
slider.slideIndex = 1;
slider.showSlides(slider.slideIndex);
slider.setIntervals();
};
return slider;
})();
/* --------- LightBox ---------- */
var lightbox = (function() {
var lightbox = {};
lightbox.openModal = function() {
document.getElementById('myLightBox').style.display = "block";
};
lightbox.closeModal = function() {
document.getElementById('myLightBox').style.display = "none";
};
lightbox.plusSlides = function(n) {
lightbox.showSlides(lightbox.slideIndex += n);
};
lightbox.currentSlide = function(n) {
lightbox.showSlides(lightbox.slideIndex = n);
};
lightbox.showSlides = function(n) {
var i;
var slides = document.getElementsByClassName("LB-Slides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {
lightbox.slideIndex = 1
}
if (n < 1) {
lightbox.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[lightbox.slideIndex - 1].style.display = "block";
dots[lightbox.slideIndex - 1].className += " active";
captionText.innerHTML = dots[lightbox.slideIndex - 1].alt;
};
lightbox.init = function() {
lightbox.slideIndex = 1;
lightbox.showSlides(lightbox.slideIndex);
};
return lightbox;
})();
slider.init(); // initialize slider module (widget);
lightbox.init(); // initialize lightbox module (widget);
Please make note that you also need to adjust your html onclick events, since it's should be called each widget methods, not global once.
P.S.: I'm not big fan of both of this code snippets from w3school (in terms of code quality, performance aspects, learning patterns), but it's completely another topic to discuss. But in order "to make it work" this link to jsbin above should help.
UPDATE: Updated the code and added a better example to clearify what I want to achieve.
I have built a slider with jQuery.
I give each element the class .active which displays the hidden elements.
Now I want a swipe animation, so that the images come from left to right.
The problem is that I already have a complex code and I don't know how to achieve that.
Here is an example what I want to achieve: https://bootsnipp.com/snippets/Padax
Here is the code
https://codepen.io/Insane415/pen/NggLxe
<div class="slider">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="http://via.placeholder.com/350x150" style="display:none;" class="active">
<img src="http://via.placeholder.com/350x150" style="display:none;">
<img src="http://via.placeholder.com/350x150" style="display:none;">
<img src="http://via.placeholder.com/350x150" style="display:none;">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-2">
<div class="thumbnails">
<img src="http://via.placeholder.com/350x150" class="active-thumbnail">
<img src="http://via.placeholder.com/350x150">
<img src="http://via.placeholder.com/350x150">
<img src="http://via.placeholder.com/350x150">
</div>
</div>
<div class="col-md-6 center-me" style="height:100%;">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h2>Giant Heading 1</h2>
<p>Just some more text</p>
zur Preisübersicht
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h2>Giant Heading 2</h2>
<p>Some more text</p>
zur Preisübersicht
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h2>Giant Heading 3</h2>
<p>Some more text</p>
zur Preisübersicht
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h2>Giant Heading 4</h2>
<p>Some more text</p>
zur Preisübersicht
</div>
</div>
</div>
</div>
.text-holder .text p{margin: 0!important;}
.slider{
padding: 15px;
margin-top: 50px;
background: url('/images/content/slider/Banner_Hintergrund_telbes-01.jpg');
background-repeat: no-repeat!important;
background-size: cover!important;
display: inline-block;
width: 100%;
border: 1px solid #ddd;
}
.slider .bullet-points a{
color: #ccc;
}
.thumbnails{
height: 195.11px;
margin-left: -25px;
}
.thumbnails img{
display:block;
max-height: 31.65%;
margin-bottom: 5px;
}
.thumbnails img:hover{
cursor: pointer;
}
.text-holder{
margin-left: 0px;
height: 100%;
}
.text-holder .text{
display: none;
}
/*display active image*/
.active{
display: block!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail{
display: none!important;
}
.bullet-points{
display: block;
text-align: center;
margin-top: 15px;
}
.bullet-points a{
font-size: 40px;
text-decoration: none;
color: #ccc;
}
.active-bullet{
color: #E22C26!important;
}
/*.image-holder{
max-width: 350px!important;
}
.image-holder img{
max-width: 350px!important;
}*/
.image-holder img{
/* text-align: center!important; */
margin: 0 auto;
}
.bullet-points a:hover{
color: #E22C26!important;
}
.center-me{
margin-top: 4%;
}
.text-holder a{
margin-top: 15px;
padding: 10px 20px 10px 20px;
}
.text-holder a:hover{
padding:10px 20px 10px 20px;
}
.text-holder{
font-size: 130%;
color: inherit;
}
.text-holder h2{
font-size: 200%;
}
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var backgrounds = ["url('/images/content/slider/Banner_Hintergrund_telbes-01.jpg')", "url('/images/content/slider/Banner_Hintergrund_telbes-02.jpg')", "url('/images/content/slider/Banner_Hintergrund_telbes-03.jpg')", "url('/images/content/slider/Banner_Hintergrund_telbes-04.jpg')"];
var bullets = [$(".bullet-points a:first-child"), $(".bullet-points a:nth-of-type(2)"), $(".bullet-points a:nth-of-type(3)"), $(".bullet-points a:last-child")];
var i = 1;
var currentSlide = 1;
var time = 3000;
var sliderTimer = setInterval(slider, time);
// slider navigation
$('.bullet-points a, .thumbnails img').click(function(e) {
e.preventDefault();
var pos = $(this).index();
clearInterval(sliderTimer); // stop auto slideshow
sliderTimer = false;
slider(pos);
});
function slider(pos) {
currentSlide = i;
if (typeof(pos) !== 'undefined') {
i = pos;
images[currentSlide - 1].removeClass("active").addClass('transition');
text[currentSlide - 1].removeClass("active");
thumbnails[currentSlide - 1].removeClass("active-thumbnail");
bullets[currentSlide - 1].removeClass("active-bullet");
}
if (i != 0) {
images[i - 1].removeClass("active").addClass('transition');
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
bullets[i - 1].removeClass("active-bullet");
}
if (i == images.length) { i = 0 }
images[i].addClass("active");
setTimeout(function() {
$(".image-holder img").removeClass('transition');
},1000);
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
bullets[i].addClass("active-bullet");
i++;
if (!sliderTimer) {
sliderTimer = setInterval(slider, time); // start auto slideshow
}
}
});
You can do something like this using using CSS3,
Give each image an absolute position and give each image a width & height value.
Set the image container height so your slider pager sit below the images.
I use both #keyframes and transition to demonstrate how you can achieve the effect.
And in your javascript slider function, I added a function to add and remove the transition.
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var bullets = [$(".bullet-points a:first-child"), $(".bullet-points a:nth-of-type(2)"), $(".bullet-points a:nth-of-type(3)"), $(".bullet-points a:last-child")];
var i = 1;
var currentSlide = 1;
var time = 3000;
var sliderTimer = setInterval(slider, time);
// slider navigation
$('.bullet-points a, .thumbnails img').click(function(e) {
e.preventDefault();
var pos = $(this).index();
clearInterval(sliderTimer); // stop auto slideshow
sliderTimer = false;
slider(pos);
});
function slider(pos) {
currentSlide = i;
if (typeof(pos) !== 'undefined') {
i = pos;
images[currentSlide - 1].removeClass("active").addClass('transition');
text[currentSlide - 1].removeClass("active");
thumbnails[currentSlide - 1].removeClass("active-thumbnail");
bullets[currentSlide - 1].removeClass("active-bullet");
}
if (i != 0) {
images[i - 1].removeClass("active").addClass('transition');
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
bullets[i - 1].removeClass("active-bullet");
}
if (i == images.length) { i = 0 }
images[i].addClass("active");
setTimeout(function() {
$(".image-holder img").removeClass('transition');
},1000);
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
bullets[i].addClass("active-bullet");
i++;
if (!sliderTimer) {
sliderTimer = setInterval(slider, time); // start auto slideshow
}
}
});
/*how I could allign the images in one row*/
.image-holder {
display: inline-block;
width: 100%;
height: 220px;
}
.image-holder img {
display: block;
width: 200px;
height: 200px;
margin: 0;
opacity: 0;
top: 0;
left: 100%;
transition: left ease 1s;
position: absolute;
}
.image-holder img.transition {
animation: moveSlider ease 2s;
opacity: 1;
}
#keyframes moveSlider {
0% {
left: 50%;
}
50% {
left: -100%;
}
100% {
opacity: 0;
left: 100%;
}
}
.image-holder img.active {
left: 50%;
transform: translateX(-50%);
opacity: 1;
}
/*END image row allignment*/
.text-holder p{margin: 0;}
.slider{
padding:15px;
margin-top: 50px;
/*background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHzNrZnq-4-FItozqSu2ZWCBXW4LjWKTlkOOgDlZFj-JtdTuclVQ');*/
background-color: blue;
background-repeat: no-repeat;
background-size: 100% 100%;
display: inline-block;
width: 100%;
}
.thumbnails {
height: 100%;
}
.thumbnails img {
width: 100%;
height: auto;
display: block;
margin-bottom: 5px;
}
.thumbnails img:hover{
cursor: pointer;
}
.text-holder .text {
display: none;
}
.text-holder .text.active {
display: block;
}
/*display active image*/
.active {
}
.active-bullet{
color: #E22C26!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail{
display: none!important;
}
.bullet-points{
display: block;
text-align: center;
}
.bullet-points a{
font-size: 40px;
text-decoration: none;
color: #ccc;
}
.bullet-points a:hover{
color: #E22C26!important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-1">
<div class="thumbnails">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active-thumbnail">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
</div>
<div class="col-md-7">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h1>Giant Heading 1</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 2</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 3</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 4</h1>
<p>Some more text</p>
</div>
</div>
</div>
</div>
</div>