In the code below, when I click on one of the two images it opens a gallery, and if I click on the other one it should open a different gallery. It works, but not as I expected because as you can see on the snippet there are some empty slides in each gallery. Can you help me solve this problem? Thank you!
// Get the image and insert it inside the modal
function imgg(id){
var modal = document.getElementById(id);
var modalImg = document.getElementById('mySlides');
modal.style.display = "block";
modalImg.src = this.src;
}
// When the user clicks on <span> (x), close the modal
function clos(id) {
var modal = document.getElementById(id);
modal.style.display = "none";
}
// Sliseshow
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length} ;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
#myImg {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
#myImg:hover {opacity: 0.7;}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
}
/* Modal Content (image) */
.mySlides {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
box-shadow: 0px 0px 50px -6px #000;
}
#-webkit-keyframes zoom {
from {-webkit-transform:scale(0)}
to {-webkit-transform:scale(1)}
}
#keyframes zoom {
from {transform:scale(0)}
to {transform:scale(1)}
}
/* The Close Button */
.close {
position: absolute;
top: 15px;
right: 100px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
/* 100% Image Width on Smaller Screens */
#media only screen and (max-width: 700px){
.mySlides {
width: 100%;
}
}
.w3-btn-floating {
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="test.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
</head>
<body>
<img id="myImg" onClick="imgg('myModal')" src="http://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg" alt="" width="300" height="200">
<img id="myImg" onClick="imgg('myModal1')"src="http://cue.me/kohana/media/frontend/js/full-page-scroll/examples/imgs/bg2.jpg" alt="" width="300" height="200">
<!-- The Modal -->
<div id="myModal" class="modal">
<span onclick="clos('myModal')" class="close">×</span>
<img class="mySlides" id="img_modal" src="http://cue.me/kohana/media/frontend/js/full-page-scroll/examples/imgs/bg2.jpg" >
<img class="mySlides" id="img_modal" src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg" >
<a class="w3-btn-floating" style="position:absolute;top:45%;left:280px;" onclick="plusDivs(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:280px;" onclick="plusDivs(1)">❯</a>
</div>
<div id="myModal1" class="modal">
<span onclick="clos('myModal1')" class="close">×</span>
<img class="mySlides" id="img_modal" src="http://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg" >
<img class="mySlides" id="img_modal" src="http://i.dailymail.co.uk/i/pix/2016/03/22/13/32738A6E00000578-3504412-image-a-6_1458654517341.jpg" >
<a class="w3-btn-floating" style="position:absolute;top:45%;left:280px;" onclick="plusDivs(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:280px;" onclick="plusDivs(1)">❯</a>
</div>
</body>
</html>
I'm not 100% sure, but this line
var x = document.getElementsByClassName("mySlides");
should return 4 items. That would explain why you are getting 2 empty slides in your slider. Try filtering first by id (e.g. "myModal" or "myModal1") and afterwards get the number of the contained "mySlides"-classes.
so you can do it like this:
var activeModalId = "";
// Get the image and insert it inside the modal
function imgg(id){
activeModalId = id;
var modal = document.getElementById(activeModalId);
var modalImg = modal.getElementsByClassName('mySlides');
modal.style.display = "block";
showDivs(0);
}
// When the user clicks on <span> (x), close the modal
function clos() {
var modal = document.getElementById(activeModalId);
modal.style.display = "none";
activeModalId = "";
}
// Sliseshow
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementById(activeModalId).getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1;}
if (n < 1) {slideIndex = x.length;}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
On top, you declare your active modal. It will be set, reused, and removed by your functions.
From what I can see there are some url typos.
For example: you have ihttp where it should be http.
In the mouse one there's an unnecessary url termination after .jpg: ?1448476701
you need to pass "this" into function like
onClick="imgg('myModal',this)"
now in function get it
function imgg(id,this){
var modal = document.getElementById(id);
var modalImg = document.getElementById('mySlides');
modal.style.display = "block";
modalImg.src = this.src;}
Related
I am creating a gallery in PHP. Clicking on each thumbnail should open a modal window with the image and other information.
The problem is that it only works with the first thumbnail and not with the others.
this is part of the php code:
while($i !== $nIMG){
$recordIMG = $q->fetch(PDO::FETCH_ASSOC);
echo "<div class='content-img'><img src='". $recordIMG['urljpg'] ."' id='infoIMG'></div>";
$i++;
}
this is the modal window
<div class="modal" id="myModal">
<img class="modal-content" id="img01">
</div>
this is the javascript code
var modal = document.getElementById("myModal");
var img = document.getElementById("infoIMG");
var modalImg = document.getElementById("img01");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
}
I am thinking it is an ID issue which must be unique. But I don't know how to solve, could someone more experienced help me?
In that case, the php part was okay. Add onclick="openImage(this)" to it, and than move to the javascript part.
There, you would need a new function to pass the image src. I also re-named the modal image class to a more general one: image-content
// Get the modal
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("image-content");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// Look at this code: element is passed to the function
function openImage(element) {
modal.style.display = "block";
// This is where the magic happens :)
modalImg.src = element.src;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
padding-top: 100px;
/* Location of the box */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
/* The Close Button */
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Modal Example</h2>
<!-- Trigger/Open The Modal -->
<div class='content-img'><img src="https://picsum.photos/100/100?random=1" onclick="openImage(this)"></div>
<div class='content-img'><img src="https://picsum.photos/100/100?random=2" onclick="openImage(this)"></div>
<div class='content-img'><img src="https://picsum.photos/100/100?random=3" onclick="openImage(this)"></div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content" id="myModal">
<span class="close">×</span>
<img class="modal-content" id="image-content">
</div>
</div>
</body>
</html>
before getting your answer i tried to create two for loops in php and javascript and it works. These are the codes:
PHP:
$n = 0;
for($i = 0; $i !== $nIMG; $i++){
$n++;
$recordIMG = $q->fetch(PDO::FETCH_ASSOC);
echo "<div class='content-img'><img src='". $recordIMG['urljpg'] ."' id='infoIMG".$n."'></div>";
}
Javascript:
var nr = 0;
for(i = 0; i < 100; i++){
nr++;
var y = "infoIMG" + nr;
var img = document.getElementById(y);
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("img01");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
}
}
Everything seems to work fine. Do you think it might be okay or is it better to use the code reported by you?
If I use this code, the only doubt is to understand how to pass the number of rows of the mysql database as the second parameter of the JS for loop.
i wanted to create a sliding image gallery in a div. To get the images and the description i make a get request on an api. The returned json is as expected and until that, the code works.
I have found this sliding gallery on W3Ccourses https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto and i wanted to use it with my data.
I get these 2 errors:
Unable to get property 'style' of undefined or null reference Here is the code
'require' is not defined
i have tried with require.js but it didn't work. I tried to create my div even with document.createElement and then .appendChild but it didn't work. I don't think the issue is in creating the html element. Thanks for replying
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {box-sizing: border-box;}
body {font-family: Verdana, sans-serif;}
.mySlides {display: none;}
img {vertical-align: middle;}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* 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 {
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active {
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}
}
/* On smaller screens, decrease text size */
#media only screen and (max-width: 300px) {
.text {font-size: 11px}
}
</style>
</head>
<!-- ####################################################### -->
<body>
<div class="slideshow-container">
<!-- ### want to get this kind of div , but with my data ###
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="img_nature_wide.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div> -->
<script type="text/javascript">
url = 'http://www.myUrl.com';
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var httpReq = new XMLHttpRequest();
httpReq.open("GET" , url , false);
httpReq.send(null);
var jsonObj = JSON.parse(httpReq.responseText);
var description = jsonObj[i].description
for ( i = 0 ; i < 9 ; i++) {
document.writeln('<div class=\"mySlides fade\">');
document.writeln('<div class = \"numbertext\">' + i + '/9</div>');
document.writeln('<img src=\"' + jsonObj[i].url_image + '\" style="width :100%">');
document.writeln('<div class=\"text\">' + description + '</div>');
}
</script>
</div>
<div style="text-align:center">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<script>
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
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";
setTimeout(showSlides, 2000); // Change image every 2 seconds
}
</script>
</body>
</html>
I checked you code and I notice three things,
You don't need this line var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; you don't need to require it here as the XMLHttpRequest is part of the windows object.
Your usage of the xmlhttprequest method is wrong see correct implementation below.
var url = 'http://www.myUrl.com';
var httpReq = new XMLHttpRequest();
httpReq.open("GET" , url);
httpReq.send(null);
var jsonObj, description;
httpReq.onload = function() {
if (httpReq.status == 200) { // analyze HTTP status of the response
var jsonObj = JSON.parse(httpReq.responseText);
var description = jsonObj[i].description // e.g. 404: Not Found
for ( i = 0 ; i < 9 ; i++) {
document.writeln('<div class=\"mySlides fade\">');
document.writeln('<div class = \"numbertext\">' + i + '/9</div>');
document.writeln('<img src=\"' + jsonObj[i].url_image + '\" style="width :100%">');
document.writeln('<div class=\"text\">' + description + '</div>');
}
var slideIndex = 0;
showSlides();
} else { // show the result
alert(`Error: httpReq.status`); // responseText is the server
}
};
You will get a CORS error if you are not running this from the same origin as http://www.myUrl.com
Hope this helps.
You can use ajax request to retrieve your json data, then loop each object while appending a mySlides div
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$.getJSON("https://jsonplaceholder.typicode.com/todos/1", function(result){
$.each(result, function(i, field){
$("div.slideshow-container").append(`<div class="mySlides fade"><div class="numbertext">1 / 3</div><img src="${field.url}" style="width:100%"><div class="text">${field.caption}</div></div>`);
});
});
showSlides();
});
</script>
I am creating an image 'slider' to embellish a landing page on a site. I created a successful, functional slider, though hope to push this further...
I'm hoping to add in an element that creates crossfading images on click (once a tile is selected from beneath the main image space), such as is detailed on the site here (beneath Demo 6 -Fading between multiple images on click)
I have tried integrating the code on this site into the pre-existing JS I have added (within the HTML), though it appears to interfere with the existing elements. The JSFiddle for the current code is here.
#charset "utf-8";
/* CSS Document */
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
.main-slide {
height: 250px;
width: 750px;
margin: auto;
}
.selection-panel {
opacity: 0.6;
filter: alpha(opacity=60);
}
.selection-panel:hover {
opacity:1.0;
filter: alpha(opacity=100);
}
.selection-panel-off {
opacity: 1.0;
filter: alpha(opacity=100);
}
.margins {
margin-top: 16px!important;
margin-bottom: 16px!important;
}
.image-spacing,.image-spacing>.single-col {
padding: 0 8px;
}
.single-col {
float: left;
width: 100%;
}
.single-col.third {
width: 33.33333%;
}
.image-spacing::after,.image-spacing::before {
content: "";
display: table;
clear: both;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Homepage Baner Module</title>
<link rel="stylesheet" href="formatting.css" type="text/css" media="screen">
<style>
.mySlides {display:none}
.demo {cursor:pointer}
</style>
</head>
<body>
<div class="main-image" style="max-width:750px">
<img class="mySlides" src="https://dummyimage.com/750x250/ff5100/fff" height="250px" width="100%">
<img class="mySlides" src="https://dummyimage.com/750x250/00ff51/fff" height="250px" width="100%">
<img class="mySlides" src="https://dummyimage.com/750x250/0055ff/fff" height="250px" width="100%">
<div class="margins image-spacing">
<div class="single-col third">
<img class="demo selection-panel" src="https://dummyimage.com/750x250/ff5100/fff" style="width:100%" onclick="currentDiv(1)">
</div>
<div class="single-col third">
<img class="demo selection-panel" src="https://dummyimage.com/750x250/00ff51/fff" style="width:100%" onclick="currentDiv(2)">
</div>
<div class="single-col third">
<img class="demo selection-panel" src="https://dummyimage.com/750x250/0055ff/fff" style="width:100%" onclick="currentDiv(3)">
</div>
</div>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" selection-panel-off", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " selection-panel-off";
}
</script>
</body>
</html>
Here's one way to do this. This example assumes your images will all fit in the same size container nicely. If not, you may want to switch to background images. First, we'll put all the .mySlides in their own container element:
<div class="slides-container">
<img class="mySlides initopacity" src="https://dummyimage.com/750x250/ff5100/fff" height="250px" width="100%">
<img class="mySlides" src="https://dummyimage.com/750x250/00ff51/fff" height="250px" width="100%">
<img class="mySlides" src="https://dummyimage.com/750x250/0055ff/fff" height="250px" width="100%">
</div>
Then we'll position those slides absolutely, relative to the container:
.slides-container{
width: 750px;
height: 250px;
position: relative;
overflow: hidden;
}
.mySlides {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
This way, they're all on top of each other. Now, you'll notice, they all have the opacity of 0, but the first .mySlide element has a class called .initopacity. That one we'll keep visible on load:
.initopacity {
opacity: 1;
}
Now, all we need is a way to change the opacity on each slide upon click. We'll use some transitions for that:
.fadeout {
opacity: 0;
transition: opacity 1s linear;
}
.fadein {
opacity: 1;
transition-delay: 1s;
transition-property: opacity;
transition-duration: 1s;
}
So now, our showDivs function just adds and removes classes, instead of changing the display properties:
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
/* x[i].style.display = "none"; */
x[0].classList.remove('initopacity');
x[i].classList.remove('fadein');
x[i].classList.add('fadeout');
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" selection-panel-off", "");
}
x[slideIndex-1].classList.remove('fadeout')
x[slideIndex-1].classList.add('fadein')
/* x[slideIndex-1].style.display = "block"; */
dots[slideIndex-1].className += " selection-panel-off";
}
See fiddle: https://jsfiddle.net/pt5bLxv2/87/
Hey I'm trying to make a function that fills an empty container of a slideshow with images, with each image being contained in it's own div.
My webpage have an undetermined amount of modal images which , when clicked, open a slideshow album of images. I got this working for 1 image then realized that to have it work for an undetermined amount of slideshows of undetermined size I should make a function that fills the slideshow div. I planned to have each modal image to have a data attribute of "1,2,3...etc" and have a bunch an array with multiple objects each named similarly "1,2,3...etc" then I'd use this information to create and append the correct divs and images to the slideshow container. I will post what I want the slideshow container div to look like, my existing code, and a fiddle of what is supposed to happen. I am new to javascript and appreciate the help. I'm not certain what I've done incorrectly here, and If I haven't explained well enough then I will add more.
Edit:
I have noticed that in my modal image, if in the onClick I put fillSlides first, the other two functions won't work (or won't be called), but if I put it at the end it opens an empty slideshow. I don't get why.
https://jsfiddle.net/nhk3o0m1/26/
Current HTML:
<body >
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
What I want my .modal-content div to look like after the function runs:
<div class="modal-content">
<div class="mySlides">
<img src="Images/LS_01.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_02.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_03.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_04.jpg" class="img">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
Javascript:
function fillSlides(modalID) {
var container = document.getElementsByClassName("modal-content");
var slides = {
"1": ["Images/LS_01.jpg", "Images/LS_02.jpg", "Images/LS_03.jpg", "Images/LS_04.jpg"],
"2": ["Images/LS_05.jpg", "Images/LS_06.jpg", "Images/LS_07.jpg", "Images/LS_08.jpg"],
"3": ["Images/LS_09.jpg", "Images/LS_10.jpg", "Images/LS_11.jpg", "Images/LS_12.jpg"]
};
var modal_num = modalID.getAttribute('data-modal');
for (var i = slides[modal_num].length; i > 0; i--) {
var the_divs = document.createElement('div');
var s_img = document.createElement('img');
the_divs.className = 'mySlides';
s_img.src = slides[modal_num][i];
the_divs.appendChild(s_img);
container.appendChild(the_divs);
}
}
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
Added a function that generates slides on the fly. There are no slides in HTML and arrow controls are in #content. You gave no details on how album exists so I made a thumbnail for 2 extra albums. Also, there's a solution to your problem concerning the removal of everything with the arrows being the exception. The CSS is a little wonky but I'm sure you can rectify it easily enough.
Details commented in demo
Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title></title>
<style>
html,
body {
height: 100%;
width: 100%
}
body {
font-family: Verdana, sans-serif;
margin: 0;
}
* {
box-sizing: border-box;
}
.img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
}
.row {
display:flex;
justify-content:space-between;
}
.column {
width: 25%;
padding: 0 8px;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
background: rgba(0, 0, 0, 0.9);
}
/* Modal Content */
.modal-content {
position: relative;
background-color: rgba(0, 0, 0, 0.9);
margin: auto;
padding: 0;
width: 100%;
max-width: 1200px;
}
/* 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;
}
/* 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);
text-decoration: none;
}
/* Number text (1/3 etc) */
.nth {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
right: 0;
}
img {
margin-bottom: -4px;
cursor: pointer
}
img.hover-shadow {
transition: all .2s ease-in-out;
}
.hover-shadow:hover {
transform: scale(1.1);
}
.modal-content {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
.slide img {
display: block;
height: 100%;
margin: 0 auto;
margin-bottom: 50px;
}
.slide {
text-align: center;
height: 80vh;
display: none;
}
.cap {
font-size: 1.5em;
background: rgba(0, 0, 0, .4);
position: absolute;
z-index: 2;
left: 0;
top: 0;
right: 0;
text-align: center;
color: #fff
}
.act {
display: block
}
</style>
</head>
<body>
<header>
<div class="row">
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img0, cap0);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img1, cap1);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img2, cap2);openModal();"
class="hover-shadow"> </div>
</div>
</header>
<section id="box">
<div id="xModal" class="modal"> <span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content" id='content'> <a class="prev" onclick="plusSlides(-1)">❮</a> <a class="next"
onclick="plusSlides(1)">❯</a> </div>
</div>
</section>
<footer> </footer>
<script>
/* 3 arrays are required:
|= 1. An array of strings.
|| Each represents a src of an image
|= 2. An array of strings. Each represents the
|| text of a figcaption
|= 3. An empty array
|| For each additional album add #1 and #2, #3
|| is emptied and reused at the beginning of
|| a new cycle.
*/
// Album 0
var img0 = [
"http://www.catholicevangelism.org/wp-content/uploads/2013/06/1200x800.gif",
"http://chasingseals.com/wp-content/uploads/2014/02/greenlandBanner2000x800.jpg",
"http://www.a1carpet-to.com/wp-content/uploads/2015/08/600x400.png",
"https://support.kickofflabs.com/wp-content/uploads/2016/06/800x1200.png"
];
var cap0 = ['caption1', 'caption2', 'caption3', 'caption4'];
// Album 1
var img1 = [
'https://d3i6fh83elv35t.cloudfront.net/newshour/app/uploads/2016/05/729665main_A-BlackHoleArt-pia16695_full-1024x576.jpg',
'http://cdn.newsapi.com.au/image/v1/85fb305132eb20ebbb01af386983c8a1',
'http://science.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/Science/Images/Content/neptune-pia01492-ga.jpg',
'https://cdn.spacetelescope.org/archives/images/wallpaper1/heic1509a.jpg',
'https://i.giphy.com/media/JCUyexH8Zaf8k/giphy.webp'
];
var cap1 = ['Title I', 'Title II', 'Title III', 'Title IV',
'Title V'
];
// Album 2
var img2 = [
'https://i.ytimg.com/vi/YeQnLnRvZ9Y/maxresdefault.jpg',
'https://www.thesun.co.uk/wp-content/uploads/2017/08/nintchdbpict000319076839.jpg?strip=all&w=960',
'https://i0.wp.com/www.sketchysloth.com/wp-content/uploads/2016/07/Legendary-Hanging-Garden-Of-Babylon.jpg?fit=710%2C495&ssl=1',
'https://i.ytimg.com/vi/YoRvJcgSDE4/maxresdefault.jpg',
'https://www.realmofhistory.com/wp-content/uploads/2017/01/mausoleum-at-halicarnassus-restored_1.jpg',
'http://www.ancient-origins.net/sites/default/files/field/image/statue-of-Zeus-Olympia.jpg',
'https://i.ytimg.com/vi/F2yYkbinGnc/maxresdefault.jpg'
];
var cap2 = ['Colossus of Rhodes', 'Great Pyramid of Giza',
'Hanging Gardens of Babylon', 'Lighthouse of Alexandria',
'Mausoleum at Halicarnassus', 'Statue of Zeus at Olympia',
'Temple of Artemis at Ephesus'
];
// Declare a empty array
var data = [];
// Declare some counters outside of loop (or inside of loop using let)
var i, b, x;
// Reference the node that will contain the slides
var con = document.getElementById('content');
/* On each iteration...
|= Empty the data array
|= Create an object...
|| add a value from img[] to the src property
|| add a value from cap[] to the cap property
|| add the current value of index +1 to pos property
|| push the object into data array
*/
// Get the total length of data array
// Call genSlides()
function album(img, cap) {
data.length = 0;
for (i = 0; i < img.length; i++) {
var ele = new Object;
ele.src = img[i];
ele.cap = cap[i];
ele.pos = i + 1;
data.push(ele);
}
var qty = data.length;
genSlides(qty)
}
console.log(data);
/* Pass qty through...
|= On each iteration...
|= Create a documentFragment
|| it will allow us to append new elements to
|| it while still not in the DOM
|| which is faster because tasks within the DOM
|| are slow for the browser in comparison.
|= Notice that the data array is being used
|| to assign unique values.
*/
function genSlides(qty) {
for (b = 0; b < qty; b++) {
var frag = document.createDocumentFragment();
var slide = document.createElement('figure');
slide.id = 's' + b;
slide.className = 'slide';
var cap = document.createElement('figcaption');
cap.className = 'cap';
cap.textContent = data[b].cap;
var img = document.createElement('img');
img.classsName = 'img';
img.src = data[b].src;
var nth = document.createElement('b');
nth.className = 'nth';
nth.textContent = data[b].pos + '/' + data.length;
slide.appendChild(cap);
cap.appendChild(nth);
slide.appendChild(img);
frag.appendChild(slide);
con.appendChild(frag);
}
return false;
}
/* To avoid redundancy call sub functions within an initiating function
|| currentSlide() should start at 0, remember that all indexes by
|| default start at 0 and that the last index is .length - 1
|| showSlides() has ben corrected.
*/
function openModal() {
document.getElementById('xModal').style.display = "block";
showSlides(slideIndex);
currentSlide(0);
}
/* To remove what's in #content with the exception of the arrows we
|| gather all .slides in a NodeList and use a loop to remove them.
*/
function closeModal() {
document.getElementById('xModal').style.display = "none";
var slides = document.querySelectorAll(".slide");
for (x = 0; x < slides.length; x++) {
con.removeChild(slides[x]);
}
}
var slideIndex = 0;
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.querySelectorAll(".slide");
if (n > slides.length - 1) {
slideIndex = 0
}
if (n < 0) {
slideIndex = slides.length - 1
}
// Flipping a class is much cleaner than relying on style
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove('act');
}
slides[slideIndex].classList.add('act');
}
</script>
</body>
</html>
I'm trying to write some Javascript for a Drupal site we run. Ideally this would run on all the pages whenever the DOM class is used. This is what I have so far:
window.onload = function () {
// Get the modal
var modal = ["m1", "m2", "m3", "m4", "m5"];
for (var i = 0; i < modal.length; i++){
document.getElementById(modal[i]);
}
// Get the button that opens the modal
var btn = ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6"];
for (var i = 0; i < btn.length; i++){
document.getElementById(btn[i]);
}
// When the user clicks on the button, open the modal
for (var i = 0; i < btn.length; i++)
{
btn[i].onclick = function() {
modal[i].style.display = "block";
}
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal[i].style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal[i].style.display = "none";
}
}
}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<!-- Trigger/Open The Modal -->
<a id="myBtn">Open Me</a>
<!-- The Modal -->
<div id="modal" class="modal">
<div class="modal-content drive">
<span class="close">x</span>
<h2>Foo</h2>
<p>Random Info</p>
<p><a class="btn" href="/bar">Foo Bar</a></p>
</div>
As of now I'm getting a syntax error on this Loop
for (i = 0, i < btn.length; i++) <----This parenthesis
{
btn[i].onclick = function()
modal[i].style.display = "block";
}
Thanks for the help!
Edited: Fixed the broken JS, however, no modals will pop up. Any ideas?
This should have been a comment, but my comments are off, so I had to answer.
find this comment line:
// When the user clicks on the button, open the modal
Right below that comment, your for loop is like this:
for (var i = 0, i < btn.length; i++)
which should be :
for (var i = 0; i < btn.length; i++)
You just missed a semicolon ; after var i = 0 and added a comma , instead.
Read the error message carefully, that was a syntax error on line 77 of the mentioned file http://stacksnippets.net/js
You don't declare the variable in the scope of for loop:
for (i = 0, i < btn.length; i++)
And the next line, function is wrong, need mulstache:
btn[i].onclick = function()
The correct:
for (var i = 0; i < btn.length; i++)
{
btn[i].onclick = function(){
modal[i].style.display = "block";
}
}