问题
This is my first question, but I did read the guidelines. I hope you'll welcome me to the community with a straight answer.
I'm working on a gallery-website where JQuery is not a dependency. I'm trying to switch between a thumbnails-view of all pictures and a slideshow-view showing only one picture, namely, the one picture whose thumbnail I clicked on. Also, I want the thumbnails-view and the slideshow-view to be separate, one to not show when the other does, but I want to have them both on the same page, that is, not to have two separate pages one for each of them, and I don't want to use pop-ups for the switch. Furthermore, I want to switch back to thumbnails-view when clicking on the slideshow-view picture, and also, to switch between previous and next picture when clicking on the previous and next sides/buttons surrounding the picture. One example where this is achieved as I want it is in Milo:
https://madebyminimal.com/demo/milo/
I spent most of yesterday trying out a lot of functions in Javascript, playing around with the opacity, visibility and display CSS features, but whatever I do, the specific picture whose thumbnail I clicked on does not show, and it seems like Javascript does not respond to my clicking anything in the thumbnails visible/opaque/displayed span by modifying anything in the slideshow visible/opaque/displayed span.
Below is my code, including some of the function variants I tried, which are marked under the section Experimental Javascript. All the code until that section works well. I don't understand why the "experimental" code doesn't work, though. Does it conflict with the other functions, or is it over-ridden by them? If so, how should I modify it to get it to do all I want it to?
HTML:
<span class="wrapper-focuser" id="slideshow">
<span class="scrolling-wrapper">
<span class="prev-card" onclick="plusDivs(-1)">
</span>
<span class="next-card" onclick="plusDivs(+1)">
</span>
<span class="all-cards" onclick="allDivs()">
</span>
<div id="images">
<div class="card slide one">
<img class="picture" onclick="allDivs()" src="img/Picture1.jpg" alt="">
</div>
<div class="card slide two" onclick="allDivs()">
<img class="picture" src="img/Picture2.jpg" alt="">
</div>
<div class="card slide three">
<img class="picture" onclick="allDivs()" src="img/Picture3.jpg" alt="">
</div>
</div>
</span>
</span>
<span class="thumbnails is-visible" id="gallery">
<span class="scrolling-wrapper">
<div id="small">
<img class="thumbnail" onclick="allDivs(); plusDivs(+0); divDisp(1);" src="img/Picture1.jpg" alt="">
<img class="thumbnail" onclick="allDivs(); plusDivs(+1); divDisp(2);" src="img/Picture2.jpg" alt="">
<img class="thumbnail" onclick="allDivs(); plusDivs(+2); divDisp(3);" src="img/Picture3.jpg" alt="">
</div>
</span>
</span>
CSS:
.wrapper-focuser {
position: absolute;
height: 600px;
width: 1000px;
display: inline-block;
opacity: 0;
}
.scrolling-wrapper {
height: 600px;
width: 1000px;
float: left;
display: inline-block;
position: relative;
overflow: hidden;
text-align: center;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 20px 20px;
}
.no-cursor {
cursor: none;
}
.card {
height: auto;
display: block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.card:hover {
cursor: url("/img/all.png"), auto;
}
.prev-card {
width: 400px;
float: left;
height: auto;
display: block;
min-height: 600px;
min-width: 400px;
}
.prev-card:hover {
cursor: url("/img/prev.png"), auto;
}
.next-card {
width: 400px;
display: inline;
float: right;
height: auto;
display: block;
min-height: 600px;
min-width: 400px;
}
.next-card:hover {
cursor: url("/img/next.png"), auto;
opacity: 0.4;
}
.all-cards {
width: 200px;
position: relative;
height: auto;
display: inline-block;
min-height: 600px;
min-width: 200px;
}
.all-cards:hover {
cursor: url("/img/all.png"), auto;
}
.thumbnails {
position: absolute;
height: 600px;
width: 1000px;
display: inline-block;
visibility: hidden;
}
.thumbnail {
padding: 10px;
width: auto;
margin: 10px;
height: 200px;
}
.thumbnail:hover {
opacity: 0.4;
cursor: pointer;
}
.picture {
position: relative;
}
.is-discernable {
opacity: 1;
}
.is-visible {
visibility: visible;
}
Javascript:
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("slide");
var y = document.getElementsByClassName("picture");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.opacity = "0";
y[i].style.opacity = "0";
}
x[slideIndex-1].style.opacity = "1";
y[slideIndex-1].style.opacity = "1";
}
function allDivs() {
var x = document.getElementById("slideshow");
var y = document.getElementById("gallery");
var z = document.getElementsByClassName("scrolling-wrapper");
if (window.getComputedStyle(x).display === "none") {
x.classList.toggle('is-discernable');
y.classList.toggle('is-visible');
z.classList.toggle('no-cursor');
} else {
x.classList.toggle('is-discernable');
y.classList.toggle('is-visible');
z.classList.toggle('no-cursor');
}
}
Experimental Javascript:
var pictureIndex = 1;
transpireDivs(pictureIndex);
function divDisp(n) {
transpireDivs(pictureIndex += n);
}
function transpireDivs(n) {
var x = n;
var k = document.getElementsByClassName("one");
var l = document.getElementsByClassName("two");
var m = document.getElementsByClassName("three");
if (x == 1) {
k.classList.toggle('is-discernable');
} else if (x == 2) {
l.classList.toggle('is-discernable');
} else if (x == 3) {
m.classList.toggle('is-discernable');
}
}
I tried many other functions, and none of them worked. It's like the connexion between the wrapper and the gallery divs is short-circuited somehow, or like any new functions are over-ridden by one that I already wrote. I want to understand why that is, and some alternative solutions, such as creating two pages for the two divs that are linked by click-events, or structuring the slideshow in a different way.
Thank you all for your attention on this rather long code, and I hope my question helps others who may have a similar problem!
回答1:
I seem to have solved your problem by resolving the errors the code gave in the browser console.
- I added a listener that only executes
showDivs(slideIndex)
when the browser is done loading the page. Otherwisex
andy
will be empty at the first call, which makes thatx[slideIndex-1]
won't exist. z.classList.toggle('no-cursor');
gave an error becausez
is a list of elements, not an element.You need to loop over the elements:
for (let i = 0; i < z.length; i++) {z[i].classList.toggle('no-cursor');}
- This did not give an error, but changing
showDivs(slideIndex += n);
toshowDivs(slideIndex = n)
makes sure the right slide gets shown.
This is the replaced gallery:
<span class="thumbnails is-visible" id="gallery">
<span class="scrolling-wrapper">
<div id="small">
<img class="thumbnail" onclick="showDivFix(1);" src="img/Picture1.jpg" alt="">
<img class="thumbnail" onclick="showDivFix(2);" src="img/Picture2.jpg" alt="">
<img class="thumbnail" onclick="showDivFix(3);" src="img/Picture3.jpg" alt="">
</div>
</span>
</span>
And the code:
var slideIndex = 1;
document.addEventListener("DOMContentLoaded", function(event) {
showDivs(slideIndex);
});
function showDivFix(n) {
allDivs();
plusDivs(n);
//divDisp(n);
}
function plusDivs(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("slide");
var y = document.getElementsByClassName("picture");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.opacity = "0";
y[i].style.opacity = "0";
}
x[slideIndex-1].style.opacity = "1";
y[slideIndex-1].style.opacity = "1";
}
function allDivs() {
var x = document.getElementById("slideshow");
var y = document.getElementById("gallery");
var z = document.getElementsByClassName("scrolling-wrapper");
x.classList.toggle('is-discernable');
y.classList.toggle('is-visible');
for (let i = 0; i < z.length; i++) {
z[i].classList.toggle('no-cursor');
}
}
Good luck finishing your gallery/slider!
来源:https://stackoverflow.com/questions/49464162/how-to-toggle-between-gallery-thumbnails-and-a-specific-slideshow-image-on-the-s