JS Image Slider with specific text to each image - javascript

I've followed a tutorial about JS image sliders. I'm trying to have a text box display on each image (figured that out) but I need the text to be specific for each image. The images being grabbed from an img folder and are in order (image-0, image-1, etc). I'm guessing I'll need some array but I can't figure out how to do this in JS and have the corresponding text display on each correct image. Code provided. Any help?
HTML
<body>
<div class="images">
<div id="btns">
<button type="button" class="btn prevBtn">โ†ฉ</button>
<button type="button" class="btn nextBtn">โ†ช</button>
</div>
<div id="textBlock">
<h4>This is the image</h4>
</div>
</div>
<script src="script.js"></script>
</body>
JS
const nextBtn = document.querySelector(".nextBtn");
const prevBtn = document.querySelector(".prevBtn");
const container = document.querySelector(".images");
let counter = 0;
nextBtn.addEventListener("click",nextSlide);
prevBtn.addEventListener("click",prevSlide);
function nextSlide () {
container.animate([{opacity:"0.1"},{opacity:"1.0"}],{duration:1000,fill:"forwards"});
if(counter === 4){
counter = -1;
}
counter++;
container.style.backgroundImage = `url(img/image-${counter}.jpg`
}
function prevSlide () {
container.animate([{opacity:"0.1"},{opacity:"1.0"}],{duration:1000,fill:"forwards"});
if(counter === 0){
counter = 5;
}
counter--;
container.style.backgroundImage = `url(img/image-${counter}.jpg`
}

Since you counter is indexed 0 and goes up to ๐‘› all you need is an array:
const descriptions = [
"A nice walk in the park", // for the image counter 0
"My dog and me", // for the image counter 1
// etc.
];
than all you need to do is:
textBlock.textContent = descriptions[counter];
But...
I don't know where you found that toturial but it's a really a great example on how not to build a gallery. The animation is odd, it's overly simplistic and cannot account for multiple galleries. It's repetitive and unmodular. And the total number of slides should never be hardcoded, that's why we use a programming language after all. And yes, it can count the number of items using .length.
Code should be reusable:
class Gallery {
constructor(id, slides) {
this.slides = slides || [];
this.total = this.slides.length;
this.curr = 0;
this.EL = document.querySelector(id);
this.EL_area = this.EL.querySelector(".Gallery-area");
this.EL_prev = this.EL.querySelector(".Gallery-prev");
this.EL_next = this.EL.querySelector(".Gallery-next");
this.EL_desc = this.EL.querySelector(".Gallery-desc");
const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Preload images
this.ELs_items = this.slides.reduce((DF, item) => (DF.push(NewEL("img", item)), DF), []);
this.EL_area.append(...this.ELs_items);
// Events
this.EL_prev.addEventListener("click", () => this.prev());
this.EL_next.addEventListener("click", () => this.next());
// Init
this.anim();
}
// Methods:
anim() {
this.curr = this.curr < 0 ? this.total - 1 : this.curr >= this.total ? 0 : this.curr;
this.ELs_items.forEach((EL, i) => EL.classList.toggle("is-active", i === this.curr));
this.EL_desc.textContent = this.slides[this.curr].alt;
}
prev() {
this.curr -= 1;
this.anim();
}
next() {
this.curr += 1;
this.anim();
}
}
// Use like:
new Gallery("#gallery-one", [
{alt: "My fluffy dog and me", src: "https://picsum.photos/400/300"},
{alt: "Here, we seem happy!", src: "https://picsum.photos/300/300"},
{alt: "We are making pizza?", src: "https://picsum.photos/600/300"},
]);
.Gallery {
position: relative;
height: 300px;
max-height: 100vh;
}
.Gallery-area > * {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: opacity 0.3s;
opacity: 0;
}
.Gallery-area > *.is-active {
opacity: 1;
}
.Gallery-btns {
position: absolute;
bottom: 20px;
width: 100%;
text-align: center;
}
.Gallery-desc {
position: absolute;
top: 20px;
width: 100%;
text-align: center;
font-size: 3em;
}
<div class="Gallery" id="gallery-one">
<div class="Gallery-area"></div>
<div class="Gallery-btns">
<button type="button" class="btn Gallery-prev">โ†</button>
<button type="button" class="btn Gallery-next">โ†’</button>
</div>
<div class="Gallery-desc"></div>
</div>

Related

ReactJs increment translateX() on button click

Given :
function App() {
var xPos = 0;
const [style, setStyle] = React.useState({transform: `translateX(${xPos}px)`});
const onClick =(direction) => {
(direction === "left") ? xPos -= 100 : xPos += 100;
setStyle({transform: `translateX(${xPos}px)`});
console.log(xPos)
}
return (
<div className="main_container">
<button className="left_button" onClick={() => onClick("left")}>slide left</button>
<div className="forecast_slider" >
<div className="forecast_container" style={style} >
{forecastBuilder()}
</div>
</div>
<button className="right_button" onClick={() => onClick("right")}>slide right</button>
</div>
)
}
const forecastBuilder = () => {
const cell = [];
for(var i = 1 ; i < 8 ; i++){
cell.push(
<div className={i}>
{i}
<img src="https://imgs.michaels.com/MAM/assets/1/5E3C12034D34434F8A9BAAFDDF0F8E1B/img/0E9397ED92304202B4A25D7387A74515/M10118706_2.jpg" width="100" height="80" border="1px solid black" />
<br></br>
<span>day {i}</span>
</div>
)
}
return cell;
}
ReactDOM.render(<App />, document.querySelector("#app"));
.main_container {
display:flex;
}
.forecast_container {
display: flex;
width: 510px;
height: 130px;
margin-left: auto;
margin-right: auto;
align-items: center;
text-align: center;
transition: transform 250ms;
}
.forecast_slider {
background-color: black;
color: white;
overflow:hidden;
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>
with JSFiddle link here ,
I want to make the translateX() animation increment and decrement upon respective button click. Currently, I suspect that when I call setStyle() hook, the component gets rerendered such that the line
var xPos=0;
is read again. I was not able to find a way to increment or decrement in another way (without beforehand assigning the value of 0 such that style = {style} on the first render ignores the parameter).
Does anyone have any idea how I could solve this?
The problem is that the value of xPos is going to be set as 0 on every render, so you are not saving it's new value, it gets reset on every render.
You should store the xPos in the state as well.
const [xPos, setXpos] = useState(0)
and then increment / decrement in the function itself:
const onClick = (direction) => {
(direction === "left") ? setXpos(x => x - 100) : setXpos(x => x + 100)
}
This should work

How to condense JavaScript Using Loops

I have the following code working properly to responsively lazy load background images for a number of divs on a page:
// get frames
// REFACTOR LIST:
var frame1 = document.getElementById('frame1');
var frame2 = document.getElementById('frame2');
var frame3 = document.getElementById('frame3');
var frame4 = document.getElementById('frame4');
var frame5 = document.getElementById('frame5');
// create Lazy loader
var myLazyLoad = new LazyLoad({
elements_selector: ".lazy"
});
// load images responsively
function loadImgs() {
console.log('Loading images...');
if(window.matchMedia("only screen and (max-width:700px)").matches) {
// viewport is less than or equal to 700 pixels wide
// REFACTOR LIST:
var src1 = frame1.getAttribute('data-src-small');
var src2 = frame2.getAttribute('data-src-small');
var src3 = frame3.getAttribute('data-src-small');
var src4 = frame4.getAttribute('data-src-small');
var src5 = frame5.getAttribute('data-src-small');
} else {
// viewport is greater than 700 pixels wide
// REFACTOR LIST:
var src1 = frame1.getAttribute('data-src-large');
var src2 = frame2.getAttribute('data-src-large');
var src3 = frame3.getAttribute('data-src-large');
var src4 = frame4.getAttribute('data-src-large');
var src5 = frame5.getAttribute('data-src-large');
}
// set data-src for lazy loader
// REFACTOR LIST:
frame1.setAttribute('data-src', src1);
frame2.setAttribute('data-src', src2);
frame3.setAttribute('data-src', src3);
frame4.setAttribute('data-src', src4);
frame5.setAttribute('data-src', src5);
// tell lazy loader that the data should be re-processed
// REFACTOR LIST:
frame1.removeAttribute('data-was-processed');
frame2.removeAttribute('data-was-processed');
frame3.removeAttribute('data-was-processed');
frame4.removeAttribute('data-was-processed');
frame5.removeAttribute('data-was-processed');
// tell lazy loader to update
myLazyLoad.update();
}
// load images initially
loadImgs();
// reload images when window is resized across the 700px breakpoint
var lastWindowSize = window.innerWidth;
window.onresize = function(event) {
var currentWindowSize = window.innerWidth;
if((lastWindowSize <= 700 && currentWindowSize > 700) || (lastWindowSize > 700 && currentWindowSize <= 700)) {
loadImgs();
}
lastWindowSize = currentWindowSize;
};
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
&:focus {
outline: none;
}
}
* {
font-family: monaco, courier;
}
body {
margin: 0;
padding: 0;
}
.wrapper {
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center ;
background: #ddd;
}
p {
position: absolute;
top: 0;
left: 0;
margin: 0;
padding: 8px;
color: darkslategray;
background: gold;
}
.frame {
width: 80vw;
height: 200px;
margin: 0 0 1rem 0;
padding: 0;
position: relative;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border: 2px solid gold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/8.7.1/lazyload.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- https://stackoverflow.com/questions/50431531/lazylaoding-css-background-not-html-img-tags -->
<main class="wrapper">
<a href="#">
<div id="frame1" class="frame lazy"
data-src-small="https://source.unsplash.com/random/400x200?sig=1"
data-src-large="https://source.unsplash.com/random/1200x600?sig=1">
<p>1</p>
</div>
</a>
<a href="#">
<div id="frame2" class="frame lazy"
data-src-small="https://source.unsplash.com/random/400x200?sig=2"
data-src-large="https://source.unsplash.com/random/1200x600?sig=2">
<p>2</p>
</div>
</a>
<a href="#">
<div id="frame3" class="frame lazy"
data-src-small="https://source.unsplash.com/random/400x200?sig=3"
data-src-large="https://source.unsplash.com/random/1200x600?sig=3">
<p>3</p>
</div>
</a>
<a href="#">
<div id="frame4" class="frame lazy"
data-src-small="https://source.unsplash.com/random/400x200?sig=4"
data-src-large="https://source.unsplash.com/random/1200x600?sig=4">
<p>4</p>
</div>
</a>
<a href="#">
<div id="frame5" class="frame lazy"
data-src-small="https://source.unsplash.com/random/400x200?sig=5"
data-src-large="https://source.unsplash.com/random/1200x600?sig=5">
<p>5</p>
</div>
</a>
</main>
CodePen here
But I'd like to refactor the code to dry it up. I'm thinking for loops can be used to replace each of the 5 lists under a REFACTOR LIST: comment. My aim is to enable the code for any unknown number of divs with a class of frame.
To start, as an example, I've attempted to refactor the variable declarations at the beginning with the following loop:
var FramesQuantity = document.getElementsByClassName("frame").length
var frameVariables = [];
function createframeVariables() {
for (var i = 0; i <= FramesQuantity; ++i) {
var frameIndex = 'frame' + i;
console.log("frameIndex: " + frameIndex);
frameVariables[i] = document.getElementById(frameIndex);
}
return frameVariables;
}
createframeVariables();
console.log("frameVariables[0]: " + frameVariables[0]);
but that second console log returns null and I'm not sure if this is the right direction anyway.
Any ideas?
As was suggested, I was able to refactor the code, DRYing it up, by using .forEach with .querySelectorAll which obviated the need to set variables:
// for loop demo
document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
console.log( "index: " + index);
console.log( "frame.dataset.srcSmall: " + frame.dataset.srcSmall);
console.log( "frame.dataset.srcLarge: " + frame.dataset.srcLarge);
})
// create Lazy loader
var myLazyLoad = new LazyLoad({
elements_selector: ".lazy"
});
// load images responsively
function loadImgs(context) {
console.log('Loading images ' + context);
if(window.matchMedia("only screen and (max-width:700px)").matches) {
// viewport is less than or equal to 700 pixels wide
document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
var srcSmall = frame.dataset.srcSmall;
// set data-src for lazy loader
frame.setAttribute('data-src', srcSmall);
// tell lazy loader that the data should be re-processed
frame.removeAttribute('data-was-processed');
})
} else {
document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
// viewport is greater than 700 pixels wide
var srcLarge = frame.dataset.srcLarge;
// set data-src for lazy loader
frame.setAttribute('data-src', srcLarge);
// tell lazy loader that the data should be re-processed
frame.removeAttribute('data-was-processed');
})
}
// tell lazy loader to update
myLazyLoad.update();
}
// load images initially
loadImgs("initially");
// reload images when window is resized across the 700px breakpoint
var lastWindowSize = window.innerWidth;
window.onresize = function(event) {
var currentWindowSize = window.innerWidth;
if((lastWindowSize <= 700 && currentWindowSize > 700) || (lastWindowSize > 700 && currentWindowSize <= 700)) {
loadImgs("on resize across breakpoint");
}
lastWindowSize = currentWindowSize;
};
Forked updated version of the original CodePen here.

Building a vanilla carousel - stuck on one peice of logic

Any mentorship or guidance would be most welcomed.
I am trying to make a vanilla JS carousel and I am so close to realising my objective to build one.
However; I cannot seem to get the prev or next buttons to move the carousel backwards or forwards. The buttons "work" they go up and down in value; they do not change the style. I can see that console logging the values.
I've tried passing the function back onto itself - however, I cannot think of a way of initialising the start frame; if that is the best way.
Adding the slideIndex value into the style rule doesn't work. What I get is if you keep on pressing "prev" for example; eventually, another frame randomly pops up below.
Any help would be very much welcomed.
On a side note - is there a better way to work with variable scoping; without everything requiring this?
'use strict';
function carousel(n) {
this.slideIndex = n;
this.slides = document.querySelectorAll('.homepage_carousel_wrapper .homepage_carousel');
[...this.slides].forEach(function(x) {
x.style.display = 'none';
});
this.slides[this.slideIndex-1].style.display = "flex";
this.prev = function(n) {
this.slideIndex += n;
if (this.slideIndex < 1) {
this.slideIndex = this.slides.length;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
}
this.next = function(n) {
this.slideIndex += n;
if (this.slideIndex > this.slides.length) {
this.slideIndex = 1;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
//carousel(this.slideIndex)
}
};
window.addEventListener('load', function() {
const hp_carousel = new carousel(3);
let carouselPrev = document.getElementById('carousel_prev');
carouselPrev.addEventListener('click', function(e){
hp_carousel.prev(-1);
e.preventDefault();
e.stopPropagation();
}, false);
let carouselNext = document.getElementById('carousel_next');
carouselNext.addEventListener('click', function(e){
hp_carousel.next(1);
e.preventDefault();
e.stopPropagation();
}, false);
});
.homepage_carousel:nth-child(1) {
background-color: red;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(2) {
background-color: blue;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(3) {
background-color: green;
width: 100%;
height: 200px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>carousel</title>
</head>
<body>
<a id='carousel_prev'>prev</a>
<a id='carousel_next'>next</a>
<div class='homepage_carousel_wrapper'>
<div class='homepage_carousel'>
<h1>Frame 1</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 2</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 3</h1>
</div>
</div>
</body>
</html>
I have made some modifications to the HTML and CSS, and have rewritten most of the JavaScript.
Main Modifications
HTML
Changed the controls from links to buttons.
Moved the controls inside the carousel.
CSS
Removed repeated CSS.
JavaScript
Added spacing to make the code more readable.
Added a few comments to make the code easier to understand.
Modified the carousel constructor to allow multiple carousels to be made.
Moved the control event listeners inside the carousel constructor.
Replaced the prev() and next() functions with a changeSlide() function.
'use strict';
window.addEventListener('load', function() {
const hpCarousel = new carousel('homepage_carousel', 3);
});
function carousel(id, index) {
// Set slide index and get slides
this.slideIndex = index;
const carousel = document.getElementById(id);
this.slides = [...carousel.getElementsByClassName('slide')];
// Get controls and add event listeners
const prev = carousel.getElementsByClassName('prev')[0];
const next = carousel.getElementsByClassName('next')[0];
prev.addEventListener('click', () => {
this.changeSlide(-1);
});
next.addEventListener('click', () => {
this.changeSlide(1);
});
// Functions for managing slides
this.hideAll = function() {
this.slides.forEach(function(slide) {
slide.style.display = 'none';
});
}
this.show = function() {
this.hideAll();
this.slides[this.slideIndex - 1].style.display = 'flex';
}
this.changeSlide = function(amount) {
this.slideIndex += amount;
this.slideIndex = (this.slideIndex > this.slides.length) ? 1 :
(this.slideIndex < 1) ? this.slides.length : this.slideIndex;
this.show();
}
// Show the specified slide
this.show();
}
.slide {
width: 100%;
height: 200px;
}
.slide:nth-child(1) {
background-color: red;
}
.slide:nth-child(2) {
background-color: blue;
}
.slide:nth-child(3) {
background-color: green;
}
<div id='homepage_carousel'>
<button class='prev'>prev</button>
<button class='next'>next</button>
<div>
<div class='slide'>
<h1>Frame 1</h1>
</div>
<div class='slide'>
<h1>Frame 2</h1>
</div>
<div class='slide'>
<h1>Frame 3</h1>
</div>
</div>
</div>

Use html <a> tag with same z-index?

I have slider and when i mouseover on slider play button is displaying, but slider images are inside a tag and when play button is not hidden i can't click on images inside a tag. i tried set same z-index for both (slider images and play button) but still not working
i need to click on play button when it shown and go to link placed bottom of this play button
if it is possible please help, and sorry for my bad english.
Main question: how can i click on play button with and redirect to link placed inside a tag?
Here is image how slider looks like onmouseover and image when mouse is out of slider
here is my html code:
<style type="text/css">
#slider-play-button-container{
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button{
position: relative;
top: 25vh;
width: 2vw;
opacity: 0;
}
.slide-img{
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow:hidden;
}
</style>
<main class=content>
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="Link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">แƒฏแƒแƒœ แƒ•แƒ˜แƒ™แƒ˜: III แƒ—แƒแƒ•แƒ˜ - แƒžแƒแƒ แƒแƒ‘แƒ”แƒšแƒฃแƒ›แƒ˜</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
<a href="Another link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">แƒจแƒฃแƒ แƒ˜แƒกแƒ›แƒแƒซแƒ˜แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜: แƒ“แƒแƒกแƒแƒกแƒ แƒฃแƒšแƒ˜</h3>
<img src="https://i.imgur.com/3vDzVHa.jpg" class="slide-img">
</a>
</div>
</main>
<script>
function bid(n){return document.getElementById(n)}
function qs(n){return document.querySelector(n)}
function qsa(n){return document.querySelectorAll(n)}
let slider = bid('slider');
let arrowTop = bid('slide_arrow_top');
let arrowBottom = bid('slide_arrow_bottom');
let sliderImage = qsa('.slide-img');
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
let count = 0;
let imageOffset = 0;
let imgOffset = 0;
var slideInterval;
let sliderImageOffset;
/* autoscroll */
window.addEventListener('load',winLoadForSlide);
function winLoadForSlide(){
/* slider */
slider.addEventListener('wheel',slideMouseScroll);
arrowBottom.addEventListener('click',scrollBottom);
arrowTop.addEventListener('click',scrollTop);
function bottomSlide(){
if (count < 4) {
count++;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset);
}
function topSlide(){
if (count > 0) {
count--;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset-5);
}
function slideMouseScroll(){
if (event.deltaY < 0){
topSlide();
}else if (event.deltaY > 0){
bottomSlide();
}
}
function scrollBottom(){
bottomSlide();
}
function scrollTop(){
topSlide();
}
slideInterval = setInterval(repeatScroll,100 * 20);
function showSliderPlayButton(){
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
function hideSliderPlayButton(){
sliderPlayButton.style.transform = "scale(1)";
sliderPlayButton.style.opacity = "0";
sliderPlayButton.style.transition = "250ms";
}
[slider,arrowBottom,arrowTop,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElements => {
slideElements.addEventListener('mouseover',()=>{
clearInterval(slideInterval);
});
slideElements.ondragstart = function(){ return false; }
});
[slider,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElementsWithoutButtons => {
slideElementsWithoutButtons.addEventListener('mouseover',()=>{
showSliderPlayButton();
});
});
slider.addEventListener('mouseleave',()=>{
slideInterval = setInterval(repeatScroll,100 * 20);
hideSliderPlayButton();
});
function repeatScroll(){
if( (slider.scrollHeight - slider.scrollTop - slider.clientHeight) !== 4 ){
if (imgOffset < 4) {
imgOffset++;
}
sliderImageOffset = sliderImage[imgOffset].offsetTop;
slider.scrollTo(0,sliderImageOffset);
}else{
imgOffset = 0;
slider.scrollTo(0,0);
}
}
/* END slider */
}
/* END autoscroll */
</script>
There are a few ways to get around this problem.
One would involve getting rid of the anchor tags altogether, grouping each image inside a single container and assigning a click event listener to each one to ultimately open the link. If you then add another click listener to the arrow button which executes event.preventDefault(); the click event will be passed through to the object below - the <div> including your image.
If you want to keep the anchor tags, things are a little tricky. Luckily there are some helpful JavaScript functions, foremost document.elementsFromPoint(x,y).
If you feed the current mouse coordinates to this function - e.g. by clicking on the arrow button - it will return an array of objects below this point.
This array contains the anchor element in the background, so it's just a matter of picking it out of the array, get the link assigned to it and open it using the window.open() command.
Here's an example:
function bid(n) {
return document.getElementById(n)
}
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
sliderPlayButtonContainer.addEventListener('click', (event) => {
var list = document.elementsFromPoint(event.clientX, event.clientY)
var anchorElement = list.find(element => element instanceof HTMLImageElement && element.className == 'slide-img').parentElement;
window.open(anchorElement.href, anchorElement.target);
});
function showSliderPlayButton() {
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
sliderPlayButtonContainer.addEventListener('mouseover', () => {
showSliderPlayButton();
});
#slider-play-button-container {
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button {
position: relative;
top: 25vh;
width: 2vw;
opacity: 1;
}
.slide-img {
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow: hidden;
}
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="https://www.startpage.com" target="_blank">
<h3 class="slider-movie-name">แƒฏแƒแƒœ แƒ•แƒ˜แƒ™แƒ˜: III แƒ—แƒแƒ•แƒ˜ - แƒžแƒแƒ แƒแƒ‘แƒ”แƒšแƒฃแƒ›แƒ˜</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
</div>
parentElement property helped a lot to solve my problem
playButtonATagHref = sliderImage[imgOffset].parentElement.href;
sliderPlayButton.addEventListener('click',()=>{
window.location.href = playButtonATagHref;
});

z-Index slide show using the next button

So I have to code a button that uses z-index to go to the next picture in the slideshow. I am having difficulty trying to get it to work and I feel as though I am doing something wrong. It has to have a count of 0, 1, 2, 0, 1, 2
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Lab 5, Part 1</title>
<meta charset = "utf-8"/>
<script type = "text/javascript">
function Next() {
document.getElementById('anime1').style.zIndex = 0;
document.getElementById('anime2').style.zIndex = 1;
document.getElementById('anime3').style.zIndex = 2;
}
</script>
<style type = "text/css">
.anime1 {position: absolute;
top: 150px; left: 250px; z-index: 10;}
.anime2 {position: absolute;
top: 200px; left: 300px; z-index: 15;}
.anime3 {position: absolute;
top: 250px; left: 350px; z-index: 20;}
</style>
</head>
<body>
<h1 style= "text-align: center">Lab 5, Part 1</h1>
<p>
<div class="slideshow">
<img class = "anime1" id = "anime1" height = "300"
width = "450" src = "http://images5.fanpop.com/image/photos/29300000/Megurine-Luka-megurine-luka-29391390-1680-1050.jpg"
alt = "First Image"/>
<img class = "anime2" id = "anime2" height = "300"
width = "450" src = "http://orig06.deviantart.net/a28f/f/2015/079/9/a/hinata_final_lr_by_artgerm-d8me6vb.jpg"
alt = "Second Image"/>
<img class = "anime3" id = "anime3" height = "300"
width = "450" src = "http://images6.fanpop.com/image/photos/35700000/Hatsune-Miku-snowangel_-35736242-1600-1200.jpg"
alt = "Third Image"/>
</p>
<input type="button" value="Next" onclick="Next();">
</body>
</html>
I have looked every where online to see if anything could help me but I can't find anything
If you're willing to take a more programmatic approach, you can use an array to hold the order and iterate it to set the z-indexes.
Using this method you can
pop() the item from the end of the array and unshift() it onto the beginning, or
shift() the item from the beginning of the array and push() it onto the end.
Which allows you to easily handle any number of elements while keeping your code DRY.
I've taken the liberty of making a back button as well as the next button, to show you how easy it is when approaching it this way. I've also generalized the class names and used different placeholder images for the demo.
(function(){ // keep it safe
var slideshow = document.querySelector('.slideshow'); // store the parent
var controls = slideshow.querySelector('.controls'); // store the controls
var els = slideshow.querySelectorAll('.slide'); // store the slides
var order = Object.keys(els); // store the order
var cn; // make the class holder
// assign a click handler to the parent
controls.onclick = function(e) {
// if the class is back or next, store it, otherwise stop here
if(!(cn = (e.target.className.match(/back|next/)||[false])[0])) return;
// if back clicked, move the last element to the beginning
if(cn === "back") order.unshift(order.pop());
// if next clicked, move the first element to the end
if(cn === "next") order.push(order.shift());
// iterate the order, set the z-index of each element sequentially
for(var i in order) els[order[i]].style.zIndex = i;
}
})();
.slides { position: relative; margin-top: 5px; }
.slide { position: absolute; }
.slide2 { top: 25px; left: 25px; }
.slide3 { top: 50px; left: 50px; }
<div class="slideshow">
<div class="controls">
<button class="back">Back</button>
<button class="next">Next</button>
</div>
<div class="slides">
<img class="slide slide1" src="http://placehold.it/150x150/f9fd42/fff">
<img class="slide slide2" src="http://placehold.it/150x150/42f9fd/fff">
<img class="slide slide3" src="http://placehold.it/150x150/fd42f9/fff">
</div>
</div>
Further Reading
Array.prototype.pop() (MDN)
Array.prototype.unshift() (MDN)
Array.prototype.shift() (MDN)
Array.prototype.push() (MDN)
Don't Repeat Yourself (Wikipedia)
Are you looking for something like this: https://jsfiddle.net/5L7jk73g/
var cnt = 0;
function Next() {
if (cnt == 0) {
document.getElementById('anime1').style.zIndex = 0;
document.getElementById('anime2').style.zIndex = 1;
document.getElementById('anime3').style.zIndex = 2;
cnt++;
} else if (cnt == 1) {
document.getElementById('anime1').style.zIndex = 1;
document.getElementById('anime2').style.zIndex = 2;
document.getElementById('anime3').style.zIndex = 0;
cnt++;
} else {
document.getElementById('anime1').style.zIndex = 2;
document.getElementById('anime2').style.zIndex = 0;
document.getElementById('anime3').style.zIndex = 1;
cnt = cnt - 2;
}
}

Categories