Issue with simple jquery slider - javascript

So as a means of learning jquery I'm making my own slider where each image swipes to the left creating a nice effect, this is beacuse I change the left property of the absolutely positioned images container.
However I fail to make it move, what I do is capture the width of each image in the slider and mov the container accordingly.
My code:
$(document).ready(function() {
var interval = 2000; //will move to left 450px each X seconds
var sliders = $('.slider_image'); //counts number of sliders
var image_width = $('.slider_image').width();
var index = 0;
var show_index = 0;
var scrolledPx = 0;
setInterval(function() {
if (scrolledPx >= image_width * sliders.length - 1) {
$('.sliders_container').animate({
'left': '0px'
}, 2000);
scrolledPx = 0;
} else {
$('.sliders_container').animate({
'left': '-= ' + image_width + ''
}, 1000);
scrolledPx += image_width;
}
}, interval);
});
/*SECTION SLIDER MARG START*/
.section_slider_marg_maincontainer {
width: 100%;
height: 275px;
outline: 2px solid white;
position: relative;
overflow: hidden;
}
.section_slider_marg_items_container {
width: auto;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
display: flex;
}
.section_slider_marg_item {
height: 100%;
width: 450px;
outline: 2px solid red;
background-size: cover;
}
/*SECTION SLIDER MARG END*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="section_slider_marg_maincontainer" style="">
<div class="section_slider_marg_items_container sliders_container" style="">
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">1</div>
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">2</div>
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">3</div>
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">4</div>
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">5</div>
<div class="section_slider_marg_item slider_image" style="background-image:url('img/Res1.jpg');">6</div>
</div>
</section>

<style>
.section_slider_marg_maincontainer {
width: 100%;
height: 275px;
outline: 2px solid white;
position: relative;
overflow: hidden;
}
.section_slider_marg_items_container {
width: auto;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
display: flex;
}
.section_slider_marg_item {
height: 100%;
width: 450px;
outline: 2px solid red;
background-size: cover;
}
.slider_image {display: none}
/* Slideshow container */
.sliders_container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
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;
}
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
</style>
</head>
<body>
<div class="section_slider_marg_items_container sliders_container">
<div class="section_slider_marg_item slider_image">
<img src="res1.jpg"></div>
<div class="section_slider_marg_item slider_image">
<img src="res1.jpg"></div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<script>
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("slider_image");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
}
</script>
Check out this and let me know if it does work

Related

multiple sliders in one page website with javascript

I have to multiple sliders in my website. this code not work in my page for 3 sliders in one page.
but worked in one slider in one page. please help me do I it?
I need that this sliders worked in one page in my website. This sliders have to work into the accordion hover in one page.
The problem is that when I put all the slides, they all come together in one accordion.
In general, the main problem is that three sliders on one page do not work with this code
const slider = function () {
// const this_slider = this;
const slides = document.querySelectorAll('.slide');
const btnLeft = document.querySelector('.slider__btn--left');
const btnRight = document.querySelector('.slider__btn--right');
const dotContainer = document.querySelector('.dots');
let curSlide = 0;
const maxSlide = slides.length;
// Functions
const createDots = function () {
slides.forEach(function (_, i) {
dotContainer.insertAdjacentHTML(
'beforeend',
`<button class="dots__dot" data-slide="${i}"></button>`
);
});
};
const activateDot = function (slide) {
document
.querySelectorAll('.dots__dot')
.forEach(dot => dot.classList.remove('dots__dot--active'));
document
.querySelector(`.dots__dot[data-slide="${slide}"]`)
.classList.add('dots__dot--active');
};
const goToSlide = function (slide) {
slides.forEach(
(s, i) => (s.style.transform = `translateX(${100 * (i - slide)}%)`)
);
};
// Next slide
const nextSlide = function () {
if (curSlide === maxSlide - 1) {
curSlide = 0;
} else {
curSlide++;
}
goToSlide(curSlide);
activateDot(curSlide);
};
const prevSlide = function () {
if (curSlide === 0) {
curSlide = maxSlide - 1;
} else {
curSlide--;
}
goToSlide(curSlide);
activateDot(curSlide);
};
const init = function () {
goToSlide(0);
createDots();
activateDot(0);
};
init();
// Event handlers
btnRight.addEventListener('click', nextSlide);
btnLeft.addEventListener('click', prevSlide);
document.addEventListener('keydown', function (e) {
if (e.key === 'ArrowLeft') prevSlide();
e.key === 'ArrowRight' && nextSlide();
});
dotContainer.addEventListener('click', function (e) {
if (e.target.classList.contains('dots__dot')) {
const { slide } = e.target.dataset;
goToSlide(slide);
activateDot(slide);
}
});
};
slider();
/* SLIDER */
.slider {
max-width: 100rem;
height: 50rem;
margin: 0 auto;
position: relative;
/* IN THE END */
overflow: hidden;
}
.slide {
position: absolute;
top: 0;
width: 100%;
height: 50rem;
display: flex;
align-items: center;
justify-content: center;
/* THIS creates the animation! */
transition: transform 1s;
}
.slide > img {
/* Only for images that have different size than slide */
width: 100%;
height: 100%;
object-fit: cover;
}
.slider__btn {
position: absolute;
top: 50%;
z-index: 10;
border: none;
background-color: inherit;
/* background: rgba(255, 255, 255, 0.7); */
font-family: inherit;
color: white;
border-radius: 50%;
height: 5.5rem;
width: 5.5rem;
font-size: 3.25rem;
cursor: pointer;
}
.slider__btn--left {
left: 6%;
transform: translate(-50%, -50%);
}
.slider__btn--right {
right: 6%;
transform: translate(50%, -50%);
}
.dots {
position: absolute;
bottom: 5%;
left: 50%;
transform: translateX(-50%);
display: flex;
}
.dots__dot {
border: none;
background-color: #b9b9b9;
opacity: 0.7;
height: 1rem;
width: 1rem;
border-radius: 50%;
margin-right: 1.75rem;
cursor: pointer;
transition: all 0.5s;
/* Only necessary when overlying images */
/* box-shadow: 0 0.6rem 1.5rem rgba(0, 0, 0, 0.7); */
}
.dots__dot:last-child {
margin: 0;
}
.dots__dot--active {
/* background-color: #fff; */
background-color: blue;
opacity: 1;
}
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a grey background color */
.prev:hover,
.next:hover {
background-color: #f1f1f1;
color: black;
}
<div class="slider">
<div class="slide">
<img src="img/img-1.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-2.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-3.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-4.jpg" alt="">
</div>
<button class="slider__btn slider__btn--left">❮</button>
<button class="slider__btn slider__btn--right">❯</button>
<div class="dots"></div>
</div>
I have modified your html, css and script for demo.
html - added two more sliders and separated them.
css - added button colors for visibility
javascript - you can see it.
// We have to declare the function for all the sliders
// get all slider from document.
const slideContainer = document.querySelectorAll('.slider');
// lets put your function to every one of them
for(let i = 0; i < slideContainer.length; i++){
const slider = function () {
// const this_slider = this;
const slides = slideContainer[i].querySelectorAll('.slide'); // Your code was : const slides = document.querySelectorAll('.slide'); don't search the entire document, only search the slider
const btnLeft = slideContainer[i].querySelector('.slider__btn--left');
const btnRight = slideContainer[i].querySelector('.slider__btn--right');
const dotContainer = slideContainer[i].querySelector('.dots');
let curSlide = 0;
const maxSlide = slides.length;
// Functions
const createDots = function () {
slides.forEach(function (_, i) {
dotContainer.insertAdjacentHTML(
'beforeend',
`<button class="dots__dot" data-slide="${i}"></button>`
);
});
};
const activateDot = function (slide) {
slideContainer[i]
.querySelectorAll('.dots__dot')
.forEach(dot => dot.classList.remove('dots__dot--active'));
slideContainer[i]
.querySelector(`.dots__dot[data-slide="${slide}"]`)
.classList.add('dots__dot--active');
};
const goToSlide = function (slide) {
slides.forEach(
(s, i) => (s.style.transform = `translateX(${100 * (i - slide)}%)`)
);
};
// Next slide
const nextSlide = function () {
if (curSlide === maxSlide - 1) {
curSlide = 0;
} else {
curSlide++;
}
goToSlide(curSlide);
activateDot(curSlide);
};
const prevSlide = function () {
if (curSlide === 0) {
curSlide = maxSlide - 1;
} else {
curSlide--;
}
goToSlide(curSlide);
activateDot(curSlide);
};
const init = function () {
goToSlide(0);
createDots();
activateDot(0);
};
init();
// Event handlers
btnRight.addEventListener('click', nextSlide);
btnLeft.addEventListener('click', prevSlide);
document.addEventListener('keydown', function (e) {
if (e.key === 'ArrowLeft') prevSlide();
e.key === 'ArrowRight' && nextSlide();
});
dotContainer.addEventListener('click', function (e) {
if (e.target.classList.contains('dots__dot')) {
const { slide } = e.target.dataset;
goToSlide(slide);
activateDot(slide);
}
});
};
slider();
}
/* SLIDER */
.slider {
max-width: 100rem;
height: 50rem;
margin: 0 auto;
position: relative;
/* IN THE END */
overflow: hidden;
}
.slide {
position: absolute;
top: 0;
width: 100%;
height: 50rem;
display: flex;
align-items: center;
justify-content: center;
/* THIS creates the animation! */
transition: transform 1s;
}
.slide > img {
/* Only for images that have different size than slide */
width: 100%;
height: 100%;
object-fit: cover;
}
.slider__btn {
position: absolute;
top: 50%;
z-index: 10;
border: none;
background-color: black; // your was "inherit" . changed this for my visibility.
/* background: rgba(255, 255, 255, 0.7); */
font-family: inherit;
color: white;
border-radius: 50%;
height: 5.5rem;
width: 5.5rem;
font-size: 3.25rem;
cursor: pointer;
}
.slider__btn--left {
left: 6%;
transform: translate(-50%, -50%);
}
.slider__btn--right {
right: 6%;
transform: translate(50%, -50%);
}
.dots {
position: absolute;
bottom: 5%;
left: 50%;
transform: translateX(-50%);
display: flex;
}
.dots__dot {
border: none;
background-color: #b9b9b9;
opacity: 0.7;
height: 1rem;
width: 1rem;
border-radius: 50%;
margin-right: 1.75rem;
cursor: pointer;
transition: all 0.5s;
/* Only necessary when overlying images */
/* box-shadow: 0 0.6rem 1.5rem rgba(0, 0, 0, 0.7); */
}
.dots__dot:last-child {
margin: 0;
}
.dots__dot--active {
/* background-color: #fff; */
background-color: blue;
opacity: 1;
}
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a grey background color */
.prev:hover,
.next:hover {
background-color: #f1f1f1;
color: black;
}
<div class="slider">
<div class="slide">
<img src="img/img-1.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-2.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-3.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-4.jpg" alt="">
</div>
<button class="slider__btn slider__btn--left">❮</button>
<button class="slider__btn slider__btn--right">❯</button>
<div class="dots"></div>
</div>
<hr> <!-- This to separate the slider (optional)-->
<div class="slider">
<div class="slide">
<img src="img/img-1.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-2.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-3.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-4.jpg" alt="">
</div>
<button class="slider__btn slider__btn--left">❮</button>
<button class="slider__btn slider__btn--right">❯</button>
<div class="dots"></div>
</div>
<hr> <!-- This to separate the slider (optional)-->
<div class="slider">
<div class="slide">
<img src="img/img-1.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-2.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-3.jpg" alt="">
</div>
<div class="slide">
<img src="img/img-4.jpg" alt="">
</div>
<button class="slider__btn slider__btn--left">❮</button>
<button class="slider__btn slider__btn--right">❯</button>
<div class="dots"></div>
</div>

Javascript conflict: Div scrolling speed control & image shrink on scroll together

I've been wrestling with this problem for a while without success, so I'm hoping someone with greater knowledge can offer a solution.
By using a script to independently control the scroll speeds of specific divs, I've managed to create an effect along the lines of parallax scrolling:
https://neilwhitedesign.co.uk/pt_testing_area/index(scrolling).html
However, what I would also like to add, is a second script to reduce the size of the logo when the page is scrolls:
https://neilwhitedesign.co.uk/pt_testing_area/index(headershrink).html
Independently, these scripts are working exactly as I want them, but when I try to combine the two, there is a conflict and only the scrolling effect works.
Looking at similar questions posted previously, one solution was to add a further script between the two, to call a noConflict.
However, while adding this now makes the shrinking image effect work, it does so at the expense of the scrolling effect.
Is what I'm trying to achieve possible?
Is there a simple solution to get around the conflict?
Please find my html and css below:
HTML
window.onscroll = function() {
growShrinkLogo()
};
var Logo = document.getElementById("Logo");
var endOfDocumentTop = 90;
var size = 0;
function growShrinkLogo() {
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 90;
if (size == 0 && scroll > endOfDocumentTop) {
Logo.className = 'smallLogo';
size = 1;
} else if (size == 1 && scroll <= endOfDocumentTop) {
Logo.className = 'largeLogo';
size = 0;
}
}
$.fn.moveIt = function() {
var $window = $(window);
var instances = [];
$(this).each(function() {
instances.push(new moveItItem($(this)));
});
window.onscroll = function() {
var scrollTop = $window.scrollTop();
instances.forEach(function(inst) {
inst.update(scrollTop);
});
}
}
var moveItItem = function(el) {
this.el = $(el);
this.speed = parseInt(this.el.attr('data-scroll-speed'));
};
moveItItem.prototype.update = function(scrollTop) {
var pos = scrollTop / this.speed;
this.el.css('transform', 'translateY(' + +pos + 'px)');
};
$(function() {
$('[data-scroll-speed]').moveIt();
});
#charset "utf-8";
/* CSS Document */
/* 2. Clearfix*/
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1
}
/* 3. Images*/
a img {
border: none;
}
img {
max-width: 100%;
vertical-align: middle;
}
/* 4. Structure*/
body {
background: #fff;
color: #555;
line-height: 1.9;
margin: 0 auto;
}
.header {
background: white;
display: block;
margin: 0 auto;
position: fixed;
text-align: left;
width: 100%;
z-index: 99;
}
.parallax_container {
width: 100%;
}
.parallax {
padding-top: 50px;
}
.tagline {
color: white;
font-size: 75px;
position: absolute;
top: 50%;
bottom: 50%;
left: 5%;
right: 5%;
text-align: center;
cursor: pointer;
line-height: 1.2;
z-index: 97;
}
.content {
background: yellow;
height: 900px;
z-index: 98;
}
/* 5. Logo*/
.logo_container {
width: inherit;
padding: 10px;
}
#Logo {
-webkit-transition: width .5s ease;
-o-transition: width .5s ease;
transition: width .5s ease;
}
.largeLogo {
width: 350px;
}
.smallLogo {
width: 250px;
}
/* 6. Footer */
footer {
display: block;
height: 50px;
font-size: 13px;
margin: 0 auto;
padding: 25px 0 0 0;
position: relative;
text-align: center;
width: inherit;
}
<link rel="stylesheet" type="text/css" href="https://neilwhitedesign.co.uk/pt_testing_area/css.css" />
<body>
<div class="header">
<div class="logo_container"><img src="https://neilwhitedesign.co.uk/pt_testing_area/logo.png" class="largeLogo" id='Logo'>
</div>
</div>
<div class="parallax_container">
<div class="tagline" data-scroll-speed="3">This is the tagline</div>
<div class="parallax" data-scroll-speed="2"><img src="https://neilwhitedesign.co.uk/pt_testing_area/landscape.jpg" /></div>
</div>
<div class="content" data-scroll-speed="100">Content Area</div>
<footer>© 2021
<script src="https://neilwhitedesign.co.uk/pt_testing_area/js/copyright.js"></script> | All rights reserved.</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
Any guidance would be greatly appreciated.
Thanks
Neil White
You should never use on* handlers (unless you're creating a brand new element from in-memory) use .addEventListener() instead or the jQuery method .on() - that way handlers are attached to an element, not overwritten.
Place <script> tags (all of them) right before the closing </body> tag
Use classList.toggle or jQuery's .toggleClass()
You don't need two classes for big and small logo - only one.
jQuery plugins should use return to allow for methods chainability
Here's a remake of the plugin and your scripts:
// moveIt jQuery plugin
$.fn.moveIt = function() {
const $window = $(window);
const instances = [];
const updateItems = () => {
const scrTop = $window.scrollTop();
instances.forEach((inst) => inst.update(scrTop));
};
$window.on("scroll", updateItems); // Do on scroll
updateItems(); // and on page load
// Use "return" to allow $ methods chainability
return this.each(function(i, el) {
instances.push(new moveItItem(el));
});
}
function moveItItem(el) {
this.el = $(el);
this.speed = parseInt(this.el.data("scroll-speed"));
};
moveItItem.prototype.update = function(scrTop) {
this.el.css({transform: `translateY(${scrTop / this.speed}px)`});
};
// App
const $window = $(window);
const $logo = $("#Logo");
const docTop = 90;
function growShrinkLogo() {
$logo.toggleClass("small", $window.scrollTop() > docTop);
}
$window.on("scroll", growShrinkLogo); // Do on scroll
growShrinkLogo(); // and on page load
// moveIt plugin init:
$('[data-scroll-speed]').moveIt();
#charset "utf-8";
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1
}
a img {
border: none;
}
img {
max-width: 100%;
vertical-align: middle;
}
body {
background: #fff;
color: #555;
line-height: 1.9;
margin: 0 auto;
}
.header {
background: white;
display: block;
margin: 0 auto;
position: fixed;
text-align: left;
width: 100%;
z-index: 99;
}
.parallax_container {
width: 100%;
}
.parallax {
padding-top: 50px;
}
.tagline {
color: white;
font-size: 75px;
position: absolute;
top: 50%;
bottom: 50%;
left: 5%;
right: 5%;
text-align: center;
cursor: pointer;
line-height: 1.2;
z-index: 97;
}
.content {
background: yellow;
height: 900px;
z-index: 98;
}
.logo_container {
width: inherit;
padding: 10px;
}
#Logo {
-webkit-transition: width .5s ease;
-o-transition: width .5s ease;
transition: width .5s ease;
width: 350px;
}
#Logo.small {
width: 250px;
}
footer {
display: block;
height: 50px;
font-size: 13px;
margin: 0 auto;
padding: 25px 0 0 0;
position: relative;
text-align: center;
width: inherit;
}
<div class="header">
<div class="logo_container"><img src="https://neilwhitedesign.co.uk/pt_testing_area/logo.png" class="largeLogo" id='Logo'>
</div>
</div>
<div class="parallax_container">
<div class="tagline" data-scroll-speed="3">This is the tagline</div>
<div class="parallax" data-scroll-speed="2"><img src="https://neilwhitedesign.co.uk/pt_testing_area/landscape.jpg" /></div>
</div>
<div class="content" data-scroll-speed="100">Content Area</div>
<footer>© 2021 | All rights reserved.</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
It is because you declare window.onscroll twice and therefor it overwrites the first declaration. You just have to add the call of growShrinkLogo() to the second window.onscroll.
Working example:
var Logo = document.getElementById("Logo");
var endOfDocumentTop = 90;
var size = 0;
function growShrinkLogo() {
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 90;
if (size == 0 && scroll > endOfDocumentTop) {
Logo.className = 'smallLogo';
size = 1;
} else if (size == 1 && scroll <= endOfDocumentTop) {
Logo.className = 'largeLogo';
size = 0;
}
}
$.fn.moveIt = function() {
var $window = $(window);
var instances = [];
$(this).each(function() {
instances.push(new moveItItem($(this)));
});
window.onscroll = function() {
growShrinkLogo();
var scrollTop = $window.scrollTop();
instances.forEach(function(inst) {
inst.update(scrollTop);
});
}
}
var moveItItem = function(el) {
this.el = $(el);
this.speed = parseInt(this.el.attr('data-scroll-speed'));
};
moveItItem.prototype.update = function(scrollTop) {
var pos = scrollTop / this.speed;
this.el.css('transform', 'translateY(' + +pos + 'px)');
};
$(function() {
$('[data-scroll-speed]').moveIt();
});
#charset "utf-8";
/* CSS Document */
/* 2. Clearfix*/
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1
}
/* 3. Images*/
a img {
border: none;
}
img {
max-width: 100%;
vertical-align: middle;
}
/* 4. Structure*/
body {
background: #fff;
color: #555;
line-height: 1.9;
margin: 0 auto;
}
.header {
background: white;
display: block;
margin: 0 auto;
position: fixed;
text-align: left;
width: 100%;
z-index: 99;
}
.parallax_container {
width: 100%;
}
.parallax {
padding-top: 50px;
}
.tagline {
color: white;
font-size: 75px;
position: absolute;
top: 50%;
bottom: 50%;
left: 5%;
right: 5%;
text-align: center;
cursor: pointer;
line-height: 1.2;
z-index: 97;
}
.content {
background: yellow;
height: 900px;
z-index: 98;
}
/* 5. Logo*/
.logo_container {
width: inherit;
padding: 10px;
}
#Logo {
-webkit-transition: width .5s ease;
-o-transition: width .5s ease;
transition: width .5s ease;
}
.largeLogo {
width: 350px;
}
.smallLogo {
width: 250px;
}
/* 6. Footer */
footer {
display: block;
height: 50px;
font-size: 13px;
margin: 0 auto;
padding: 25px 0 0 0;
position: relative;
text-align: center;
width: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">
<div class="logo_container">
<img src="https://neilwhitedesign.co.uk/pt_testing_area/logo.png" class="largeLogo" id='Logo'>
</div>
</div>
<div class="parallax_container">
<div class="tagline" data-scroll-speed="3">
This is the tagline
</div>
<div class="parallax" data-scroll-speed="2">
<img src="https://neilwhitedesign.co.uk/pt_testing_area/landscape.jpg" />
</div>
</div>
<div class="content" data-scroll-speed="100">
Content Area
</div>
<footer>
© 2021 | All rights reserved.
</footer>

Why does one function work and the other one doesn't work? (Javascript)

I'm practicing on one project and i'm trying to use module pattern because i want to avoid global variables as much as i can.
My autoslide and dropdown menu are work fine. But when i clicked Topics then submenu will show, and in the same time my images is sliding.
Why dose my submenu suddenly disappear ?
var slideShow = (function () {
var slideImages = document.getElementsByClassName("slide");
var leftSide = document.getElementById("arrow-left");
var rightSide = document.getElementById("arrow-right");
var slideBullets = document.getElementsByClassName("bullets");
var current = 0;
function reset() {
for (let i = 0; i < slideImages.length; i++) {
slideImages[i].style.display = 'none';
slideBullets[i].classList.remove("clicked");
}
};
function showImages() {
for (let i = 0; i < slideImages.length; i++) {
slideImages[0].style.display = 'block';
slideBullets[current].classList.add("clicked");
}
};
function arrowSlide() {
leftSide.addEventListener("click", function () {
reset();
if (current === 0) {
current = slideImages.length;
}
slideImages[current - 1].style.display = 'block';
current--;
slideBullets[current].classList.add("clicked");
});
rightSide.addEventListener("click", function () {
reset();
if (current === slideImages.length - 1) {
current = - 1;
}
slideImages[current + 1].style.display = 'block';
current++;
slideBullets[current].classList.add("clicked");
});
};
function showBulletsImages() {
for (let i = 0; i < slideBullets.length; i++) {
slideBullets[i].addEventListener("click", function () {
reset();
slideImages[i].style.display = 'block';
slideBullets[i].classList.add("clicked");
current = i;
});
}
};
function autoSlide() {
setInterval(function () {
rightSide.click();
slideBullets[current].classList.add('clicked')
}, 2000);
};
return {
reset: reset(),
showImages: showImages(),
arrowSlide: arrowSlide(),
showBulletsImages: showBulletsImages(),
autoSlide: autoSlide()
};
})();
var toggleMenu = (function () {
var mainTopics = document.getElementById("maintopics");
mainTopics.addEventListener("click", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
mainTopics.classList.toggle("show");
});
document.addEventListener("click", function () {
mainTopics.classList.remove("show");
});
return {
toggleMenu: toggleMenu()
};
})();
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
#subtopics {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
#maintopics.show #subtopics {
display: block;
}
#subtopics ul {
margin: 0;
padding: 0;
}
#subtopics li {
display: block;
}
#subTopics a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
/*slideshow*/
#slideshow {
position: relative;
width: 100%;
height: 100%;
}
#slide1 {
background-image: url(https://preview.ibb.co/mV3TR7/1.jpg);
}
#slide2 {
background-image: url(https://preview.ibb.co/bSCBeS/2.jpg);
}
#slide3 {
background-image: url(https://preview.ibb.co/kgG9Yn/3.jpg);
}
.slide {
background-repeat: no-repeat;
background-position: center;
background-size: 800px 400px;
width: 800px;
height: 400px;
margin: auto;
margin-top: 40px;
}
.slide-contain {
position: absolute;
left: 50%;
bottom: 50%;
transform: translate3d(-50%,-50%,0);
text-align: center;
}
.slide-contain span {
color: white;
}
/*arrow*/
.arrow {
position: absolute;
cursor: pointer;
top: 200px;
width: 0;
height: 0;
border-style: solid;
}
.arrow:hover {
background-color: #e0dede;
transition: background-color 0.6s ease;
}
#arrow-left {
position: absolute;
border-width: 30px 40px 30px 0px;
border-color: transparent gray transparent transparent;
left: 0;
margin-left: 300px;
}
#arrow-right {
border-width: 30px 0px 30px 40px;
border-color: transparent transparent transparent gray;
right: 0;
margin-right: 300px;
}
/*bullets*/
#slidebullet {
position: relative;
top: -30px;
text-align: center;
}
.bullets {
display: inline-block;
background-color: gray;
width: 15px;
height: 15px;
border-radius: 10px;
cursor: pointer;
transition: background-color 0.6s ease;
}
.clicked {
background-color: #ff0000;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index.css" />
</head>
<body>
<header></header>
<nav>
<div id="mainmenu">
<ul>
<li>Logo</li>
<li>Home</li>
<li id="maintopics">Topics
<div id="subtopics">
<div id="column1" class="columns">
<ul>
<li>example1</li>
<li>example2</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</nav>
<div id="slideshow">
<div id="slide1" class="slide">
<div class="slide-contain">
<span>Image One</span>
</div>
</div>
<div id="slide2" class="slide">
<div class="slide-contain">
<span>Image Two</span>
</div>
</div>
<div id="slide3" class="slide">
<div class="slide-contain">
<span>Image Three</span>
</div>
</div>
<div id="slidebullet">
<div id="bullet1" class="bullets"></div>
<div id="bullet2" class="bullets"></div>
<div id="bullet3" class="bullets"></div>
</div>
<div id="arrow-left" class="arrow"></div>
<div id="arrow-right" class="arrow"></div>
</div>
<script src="jquery.js"></script>
<script src="index.js"></script>
<script>
</script>
</body>
</html>
The fact is that you hide the mainTopics when click on the documment.
You have a click on the document when you trigger the click on the arrow-right here : rightSide.click(); . ( arrow-right is, like everything else, part of the document. )
This triggers a click event on the document so it hides the mainTopics
One solution would be to use event.target inside the document click event, and condition it NOT to be the arrow-right element ( or the left-arrow if you want, it's easy to modify )
if (e.target.id != 'arrow-right') {
mainTopics.classList.remove("show");
}
As a side Note: Depending on the conditions you have, you can write this if statement in 2 more different ways
e.target.id != 'arrow-right' && mainTopics.classList.remove("show")
or
e.target.id != 'arrow-right' ? mainTopics.classList.remove("show") : ""
See code snippet below. Let me know if it works.
var slideShow = (function () {
var slideImages = document.getElementsByClassName("slide");
var leftSide = document.getElementById("arrow-left");
var rightSide = document.getElementById("arrow-right");
var slideBullets = document.getElementsByClassName("bullets");
var current = 0;
function reset() {
for (let i = 0; i < slideImages.length; i++) {
slideImages[i].style.display = 'none';
slideBullets[i].classList.remove("clicked");
}
};
function showImages() {
for (let i = 0; i < slideImages.length; i++) {
slideImages[0].style.display = 'block';
slideBullets[current].classList.add("clicked");
}
};
function arrowSlide() {
leftSide.addEventListener("click", function () {
reset();
if (current === 0) {
current = slideImages.length;
}
slideImages[current - 1].style.display = 'block';
current--;
slideBullets[current].classList.add("clicked");
});
rightSide.addEventListener("click", function () {
reset();
if (current === slideImages.length - 1) {
current = - 1;
}
slideImages[current + 1].style.display = 'block';
current++;
slideBullets[current].classList.add("clicked");
});
};
function showBulletsImages() {
for (let i = 0; i < slideBullets.length; i++) {
slideBullets[i].addEventListener("click", function () {
reset();
slideImages[i].style.display = 'block';
slideBullets[i].classList.add("clicked");
current = i;
});
}
};
function autoSlide() {
setInterval(function () {
rightSide.click();
slideBullets[current].classList.add('clicked')
}, 2000);
};
return {
reset: reset(),
showImages: showImages(),
arrowSlide: arrowSlide(),
showBulletsImages: showBulletsImages(),
autoSlide: autoSlide()
};
})();
var toggleMenu = (function () {
var mainTopics = document.getElementById("maintopics");
mainTopics.addEventListener("click", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
mainTopics.classList.toggle("show");
});
document.addEventListener("click", function (e) {
if (e.target.id != 'arrow-right') {
mainTopics.classList.remove("show");
}
});
return {
toggleMenu: toggleMenu()
};
})();
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
#subtopics {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
#maintopics.show #subtopics {
display: block;
}
#subtopics ul {
margin: 0;
padding: 0;
}
#subtopics li {
display: block;
}
#subTopics a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
/*slideshow*/
#slideshow {
position: relative;
width: 100%;
height: 100%;
}
#slide1 {
background-image: url(https://preview.ibb.co/mV3TR7/1.jpg);
}
#slide2 {
background-image: url(https://preview.ibb.co/bSCBeS/2.jpg);
}
#slide3 {
background-image: url(https://preview.ibb.co/kgG9Yn/3.jpg);
}
.slide {
background-repeat: no-repeat;
background-position: center;
background-size: 800px 400px;
width: 800px;
height: 400px;
margin: auto;
margin-top: 40px;
}
.slide-contain {
position: absolute;
left: 50%;
bottom: 50%;
transform: translate3d(-50%,-50%,0);
text-align: center;
}
.slide-contain span {
color: white;
}
/*arrow*/
.arrow {
position: absolute;
cursor: pointer;
top: 200px;
width: 0;
height: 0;
border-style: solid;
}
.arrow:hover {
background-color: #e0dede;
transition: background-color 0.6s ease;
}
#arrow-left {
position: absolute;
border-width: 30px 40px 30px 0px;
border-color: transparent gray transparent transparent;
left: 0;
margin-left: 300px;
}
#arrow-right {
border-width: 30px 0px 30px 40px;
border-color: transparent transparent transparent gray;
right: 0;
margin-right: 300px;
}
/*bullets*/
#slidebullet {
position: relative;
top: -30px;
text-align: center;
}
.bullets {
display: inline-block;
background-color: gray;
width: 15px;
height: 15px;
border-radius: 10px;
cursor: pointer;
transition: background-color 0.6s ease;
}
.clicked {
background-color: #ff0000;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index.css" />
</head>
<body>
<header></header>
<nav>
<div id="mainmenu">
<ul>
<li>Logo</li>
<li>Home</li>
<li id="maintopics">Topics
<div id="subtopics">
<div id="column1" class="columns">
<ul>
<li>example1</li>
<li>example2</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</nav>
<div id="slideshow">
<div id="slide1" class="slide">
<div class="slide-contain">
<span>Image One</span>
</div>
</div>
<div id="slide2" class="slide">
<div class="slide-contain">
<span>Image Two</span>
</div>
</div>
<div id="slide3" class="slide">
<div class="slide-contain">
<span>Image Three</span>
</div>
</div>
<div id="slidebullet">
<div id="bullet1" class="bullets"></div>
<div id="bullet2" class="bullets"></div>
<div id="bullet3" class="bullets"></div>
</div>
<div id="arrow-left" class="arrow"></div>
<div id="arrow-right" class="arrow"></div>
</div>
<script src="jquery.js"></script>
<script src="index.js"></script>
<script>
</script>
</body>
</html>
For mainTopics you have attached click event at two DOM element.
mainTopics
Document
When you click, show class is added due to mainTopics DOM click event
Due event bubbling , document capture the click event which remove the show class.
So,at the same time show class added and removed.
mainTopics.addEventListener("click", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
mainTopics.classList.toggle("show");
});
document.addEventListener("click", function () {
mainTopics.classList.remove("show");
});

Image Carousel: Force Images to take up entire div (each image)

I need a way to force each image to fill the div no matter the size of the div. I thought this is what width: 100% was supposed to do but it's not working the way I expected it to.
Link to CodePen
const carousels = document.querySelectorAll('.image-carousel');
[].forEach.call(carousels, c => {
let next = document.querySelector('.next'),
prev = document.querySelector('.previous'),
bubblesContainer = document.querySelector('.bubbles'),
inner = document.querySelector('.inner'),
imgs = document.querySelectorAll('img'),
currentImageIndex = 0,
width = 100,
bubbles = [];
for (let i = 0; i < imgs.length; i++) {
let b = document.createElement('span');
b.classList.add('bubble');
bubblesContainer.append(b);
bubbles.push(b);
b.addEventListener('click', () => {
currentImageIndex = i;
switchImg();
});
}
function switchImg() {
inner.style.left = -width * currentImageIndex + '%';
bubbles.forEach(function (b, i) {
if (i === currentImageIndex) {
b.classList.add('active');
} else {
b.classList.remove('active');
}
});
}
next.addEventListener('click', () => {
currentImageIndex++;
if (currentImageIndex >= imgs.length) {
currentImageIndex = 0;
}
switchImg();
});
prev.addEventListener('click', () => {
currentImageIndex--;
if (currentImageIndex < 0) {
currentImageIndex = imgs.length - 1;
}
switchImg();
});
switchImg();
});
img {
height: 100%;
min-width: 100%;
}
.image-carousel {
width: 100%;
height: 50vh;
overflow: hidden;
position: relative;
}
.image-carousel .inner {
display: flex;
position: absolute;
left: 0;
transition: left 0.5s;
width: 100%;
height: 100%;
}
.image-carousel .bubbles {
display: flex;
justify-content: center;
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 5px;
}
.image-carousel .bubbles .bubble {
margin: 0 1rem 0.5rem;
background: white;
border-radius: 100%;
width: 10px;
height: 10px;
display: inline-block;
opacity: 0.25;
transition: 0.1s;
cursor: pointer;
}
.image-carousel .bubbles .bubble:hover {
opacity: 0.65;
}
.image-carousel .bubbles .bubble.active {
opacity: 1;
}
.image-carousel .next::after, .image-carousel .previous::after {
content: '>';
position: absolute;
top: 50%;
right: 0;
background: white;
width: 1rem;
height: 3rem;
font-weight: bold;
transform: translatey(-50%);
line-height: 3rem;
box-sizing: border-box;
padding: 0 0.2rem;
cursor: pointer;
}
.image-carousel .previous::after {
left: 0;
content: '<';
}
<div class="container">
<div class="row">
<div class="col-12">
<div class="image-carousel">
<div class="inner">
<img class="carousel one" src="https://via.placeholder.com/100x100">
<img class="carousel two" src="https://via.placeholder.com/100x100">
<img class="carousel three" src="https://via.placeholder.com/100x100">
<img class="carousel three" src="https://via.placeholder.com/100x100">
</div>
<div class="bubbles"></div>
<div class="previous"><button><</button></div>
<div class="next"><button>></button></div>
</div>
</div>
</div>
</div>
You can try adding display:block; min-width: 100%; Min-width forces element to fill parents width.
The issue is that you've set the .inner element's display property to flex.
You can remove flex or add flex: 0 0 100% to your images like so:
.inner {
..
img {
flex: 0 0 100%;
}
}
flex: 0 0 100% is telling the element inside a flex container to not shrink, or expand, and take up 100% of its parent.

Why is my javascript not functioning?

I'm using a layout from Codepen: http://codepen.io/trhino/pen/ytoqv
and I have put certain parts of that code into my html but it is not functioning. Can anybody tell me why and what I can do to fix it? All I want from the codepen tutorial is the actual image gallery effect and the 'click to expand' and 'collapse' buttons.
Here is what my site looks like at the minute (ignore the stretched photos, I will be correcting this once I have sorted the javascript)
http://me14ch.leedsnewmedia.net/portfolio/photo.html
Really appreciate ANY help! This is my code:
<h2>(click on the box to expand gallery)</h2>
<div class="wrap">
<div id="picture1" class="deck">
<img src="http://www.me14ch.leedsnewmedia.net/portfolio/gallery/newyork1.JPG">
</a>
</div>
<div id="picture2" class="deck">
<img src="http://www.me14ch.leedsnewmedia.net/portfolio/gallery/newyork2.JPG">
</a></div>
<div id="picture3" class="deck">
<img src="http://www.me14ch.leedsnewmedia.net/portfolio/gallery/newyork3.JPG">
</a></div>
<div id="picture4" class="deck">
<img src="http://www.me14ch.leedsnewmedia.net/portfolio/gallery/newyork4.JPG">
</a></div>
<div id="picture5" class="deck">
<img src="http://www.me14ch.leedsnewmedia.net/portfolio/gallery/newyork5.JPG">
</a></div>
</div>
<div id="close"><p>« collapse gallery</p></div>
<div id="lightbox">
<div id="lightwrap">
<div id="x"></div>
</div>
This is the CSS
/* gallery */
*, *::before, *::after {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
p {
font-family: arial, helvetica, sans-serif;
font-size: 24px;
color: #6CBDEB;
text-shadow: 1px 1px 1px #000;
}
.wrap {
position: relative;
width: 1125px;
height: 200px;
margin: 0 auto;
}
.deck {
margin: 20px;
border: 3px solid #FADBC8;
height: 202px;
width: 202px;
position: absolute;
top: 0;
left: 0;
transition: .3s;
cursor: pointer;
font-size: 50px;
line-height:200px;
text-align: center;
}
.deck a {
color: black;
}
.deck img {
height: 200px;
width: 200px;
}
.album {
border: 1px solid #FADBC8;
height: 200px;
width: 200px;
float: left;
transition: .3s;
position: relative;
}
#close {
position: relative;
display: none;
width: 1125px;
margin: 30px auto 0;
}
#close p {
cursor: pointer;
text-align: right;
margin: 0 20px 0;
}
#lightbox {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.7);
display: none;
z-index: 999;
}
#lightwrap {
position: relative;
margin: 0 auto;
border: 5px solid black;
top: 15%;
display: table;
}
#lightwrap img {
display: table-cell;
max-width: 600px;
}
#x {
position: absolute;
top: 2px;
right: 2px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAAPFBMVEX///8AAAD9/f2CgoKAgIAAAAAAAAAAAABLS0sAAAAAAACqqqqqqqq6urpKSkpISEgAAAC7u7u5ubn////zbsMcAAAAE3RSTlMASv6rqwAWS5YMC7/AyZWVFcrJCYaKfAAAAHhJREFUeF590kkOgCAQRFEaFVGc+/53FYmbz6JqBbyQMFSYuoQuV+iTflnstI7ssLXRvMWRaEMs84e2uVckuZe6knL0hiSPObXhj6ChzoEkIolIIpKIO4joICAIeDd7QGIfCCjOKe9HEk8mnxpIAup/F31RPZP9fAG3IAyBSJe0igAAAABJRU5ErkJggg==);
width: 27px;
height: 27px;
cursor: pointer;
}
and this is the Javascript:
var i, expand = false;
function reset() {
$('.deck').css({
'transform': 'rotate(0deg)',
'top' : '0px'
});
}
//expands and contracts deck on click
$('.deck').click(function (a) {
if (expand) {
a.preventDefault();
var imgSource = $(this).children().attr('href');
$('#lightwrap').append('<img src="' + imgSource + '" id="lb-pic">');
$('#lightbox, #lightwrap').fadeIn('slow');
} else {
var boxWidth = $('.deck').width();
$('.deck').each(function (e) {
$(this).css({
'left': boxWidth * e * 1.1 + 'px'
});
expand = true;
$('#close').show();
});
}
});
//close lightbox
$('#x, #lightbox').click(function(){
$('#lightbox').fadeOut('slow');
$('#lightwrap').hide();
$('#lb-pic').remove();
});
//prevent event bubbling on lightbox child
$('#lightwrap').click(function(b) {
b.stopPropagation();
});
$('#close').click(function(){
$(this).hide();
$('.deck').css({'left': '0px'});
expand = false;
});
$('.deck:last-child').hover(
//random image rotation
function() {
if (expand === false) {
$('.deck').each(function () {
i++;
if (i < $('.deck').length) {
var min = -30,
max = 30,
random = ~~(Math.random() * (max - min + 1)) + min;
$(this).css({
'transform' : 'rotate(' + random + 'deg)',
'top' : random + 15 + 'px'
});
}
});
}
//straightens out deck images when clicked
$('.deck').click(
function (a) {
a.preventDefault();
reset();
});
},
//undo image rotation when not hovered
function () {
i = 0;
reset();
}
);
Just enclose your javascript in a $( document ).ready() function in order to execute on load of the page:
$( document ).ready(function() {
//paste javascript code here
});
The Result will be this:
Here is also a jsBin for it

Categories

Resources