Add class when X class is been removed via JS - javascript

I am trying to add a class to a div when another class is been removed with JS.
This is my HTML:
<body class="homepage">
<div id="wrap">
<div id="projects">
<section id="project-0" class="slide active"> Slide 1</section>
<section id="project-1" class="slide active"> Slide 2</section>
<section id="project-2" class="slide active"> Slide 3</section>
</div>
</div>
<div class="content"> Website main content </div>
This is a vertical slide, so when you scroll down, the active class is removed with JS. What I want to achieve is to add a class to body when the active is removed from project-2.
This is what I have so far, but it doesn't recognise the class active because it's been added via JS...
if(!$("#project-2").hasClass("active")){
$("body").addClass("shifted");
}
JS:
var delta = 0;
var currentSlideIndex = 0;
var scrollThreshold = 30;
var slides = $(".slide");
var numSlides = slides.length;
function elementScroll (e) {
console.log (Math.abs(delta));
// --- Scrolling up ---
if (e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0) {
delta--;
if ( Math.abs(delta) >= scrollThreshold) {
prevSlide();
}
}
// --- Scrolling down ---
else {
delta++;
if (delta >= scrollThreshold) {
nextSlide();
}
}
// Prevent page from scrolling
return false;
}
function showSlide() {
// reset
delta = 0;
slides.each(function(i, slide) {
$(slide).toggleClass('active', (i >= currentSlideIndex));
});
}
function prevSlide() {
currentSlideIndex--;
if (currentSlideIndex < 0) {
currentSlideIndex = 0;
}
showSlide();
}
function nextSlide() {
currentSlideIndex++;
if (currentSlideIndex > numSlides) {
currentSlideIndex = numSlides;
}
showSlide();
}
$(window).on({
'DOMMouseScroll mousewheel': elementScroll
});
You can see here how it works
Thanks

By looking at your JS code I believe you want to add class to body while scrolling down. You may try below code:
function prevSlide() {
currentSlideIndex--;
if(currentSlideIndex == (numSlides-1))
{
$("body").removeClass("shifted"); // remove the class from body
}
if (currentSlideIndex < 0) {
currentSlideIndex = 0;
}
showSlide();
}
function nextSlide() {
currentSlideIndex++;
if (currentSlideIndex > numSlides) {
currentSlideIndex = numSlides;
$("body").addClass("shifted"); // add the class to body
}
showSlide();
}

Your check for the absence of the class is only started once. You had to do this with an interval from 100 ms or whatever you want:
setInterval(function()
{
if (!$("#project-2").hasClass("active")){
$("body").addClass("shifted");
}
}, 100);

Related

After 2 images slided in right side, next page is blank

I want to build a slider with buttons and I can`t figure out how should I do it.
When I hit the right button it slides 2 pages then show a blank, and thinking the problem is on the arrowRight function.
If anyone knows why my code isn't working please explain to me.
//FOR SLIDER
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = 'none';
}
}
function startSlide() {
reset();
sliderImages[0].style.display = 'block';
}
startSlide();
function slideLeft() {
reset();
sliderImages[current - 1].style.display = 'block';
current--
}
arrowLeft.addEventListener('click', function () {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
})
function slideRight() {
reset();
sliderImages[current + 1].style.display = 'block';
current++
}
arrowRight.addEventListener('click', function () {
if (current === sliderImages.length) {
current = 0;
}
slideRight();
})
I don't think your method is perfect for that task. Usually it's two containers - one for visible part, other is full of images. It'll look something like this:
const sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
container = document.querySelector(".container");
document.addEventListener("DOMContentLoaded", function() {
container.style.width = 100 * sliderImages.length + "%";
sliderImages.forEach((el) => {
el.style.width = 100 / sliderImages.length + "%";
})
startSlider()
});
function startSlider() {
let pos = 0;
arrowLeft.addEventListener("click", slideLeft)
arrowRight.addEventListener("click", slideRight)
function slideLeft() {
if(pos === 0) {
pos = sliderImages.length - 1;
} else{
pos--;
}
slide()
}
function slideRight() {
if(pos === sliderImages.length - 1) {
pos = 0;
} else {
pos++;
}
slide()
}
function slide() {
$(container).animate({left: -100 * pos + "%"}, 500)
}
}
*{
padding: 0;
margin: 0;
}
body{
width: 100%;
}
.outer-container {
width: 80%;
margin: 5px auto;
overflow: hidden;
position: relative;
}
.slide > img {
width: 100%;
}
.container {
display: flex;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer-container">
<div id="arrow-left">LEFT</div>
<div id="arrow-right">RIGHT</div>
<div class="container">
<div class="slide">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80">
</div>
<div class="slide">
<img src="https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492_960_720.jpg">
</div>
<div class="slide">
<img src="https://media.boingboing.net/wp-content/uploads/2019/02/cats.jpg">
</div>
<div class="slide">
<img src="https://cdn-images-1.medium.com/max/1600/1*mONNI1lG9VuiqovpnYqicA.jpeg">
</div>
</div>
</div>
If you just a fix for your code, here's what I've changed:
arrowRight.addEventListener('click', function () {
//Make sure that's current less than the number of images
if (current + 1 == sliderImages.length) {
current = 0;
} else {
current++;
}
slide();
})
//Moved checks and current position management from slide
//Functions to click listeners
arrowLeft.addEventListener('click', function () {
if (current === 0) {
current = sliderImages.length - 1;
} else {
current--;
}
slide();
})
//That let me merge your two function into one
//And your checks for positions was a little off
function slide(){
reset();
sliderImages[current].style.display = 'block';
}
I hope my answer helped you. If you have any questions about this code add a comment below.

Javascript run 2 functions on button click with multiple buttons and same class

I have a portfolio grid that has a screenshot of past work in each grid item.
Currently on button click, it calls a function to scroll the screenshot and stop once it reaches the bottom of the image.
I need to reverse the scroll once the button is clicked again. The scroll is created by a setInterval. I have a class of "down" on the button which is removed on click.
I have an if statement that does not work to check if the class of "down" is present and run a scrollUp function.
This is a PHP loop so there are multiple buttons with same class.
I cannot use jQuery.
Thanks for any help!
HTML:
<ul>
<li>
<div class="image-container overflow-hidden height-500">
<img class="item absolute pin-t w-full h-auto pin-l"
src="/image.jpg"/>
</div>
<button class="portScroll down">Scroll Down</button>
</li>
<li class="web-design-portfolio">
<div class="image-container overflow-hidden height-500">
<img class="item absolute pin-t w-full h-auto pin-l"
src="/image.jpg"/>
</div>
<button class="portScroll down">Scroll Down</button>
</li>
</ul>
JS:
function scrollDown() {
var portImg = this.parentNode.parentNode.querySelector('img.item');
var height = portImg.clientHeight;
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == height - 500) {
clearInterval(id);
} else {
pos++;
portImg.style.top = - + pos + 'px';
}
}
for (const button of document.querySelectorAll('button.portScroll')) {
button.classList.remove('down');
}
}
for (const button of document.querySelectorAll('button.portScroll')) {
if (button.classList.contains("down")) {
button.addEventListener("click", scrollDown);
} else {
button.addEventListener("click", scrollUp);
}
}
Here is the working Codepen for scroll down:
https://codepen.io/completewebco/pen/bZeVoz
I created a single function that does what is needed. I hope that is OK.
function scrollUpOrDown(_this, state) {
var portImg = _this.parentNode.parentNode.querySelector('img.item');
var height = portImg.clientHeight;
if(state.id > -1) {
clearInterval(state.id);
state.dir *= -1;
}
if(state.pos < 0) {
state.pos = 1;
}
state.id = setInterval(frame, 5);
function frame() {
if ((state.pos == height - 500 && state.dir > 0) || (state.pos == 0 && state.dir < 0)) {
clearInterval(state.id);
} else {
state.pos += state.dir;
portImg.style.top = -+state.pos + "px";
}
}
}
for (const button of document.querySelectorAll("button.portScroll")) {
let scollingState = {
pos: -1,
id: -1,
dir: 1
};
if (button.classList.contains("down")) {
button.addEventListener("click", function(){
scrollUpOrDown(this,scollingState);
});
}
}
https://codepen.io/prtjohanson/pen/QoEyQK
If you are wondering why/how it works, look at the output of this code
var array = [0,1,2,3,4,5];
for(const i in array) {
setTimeout(function(){console.log(i)}, Math.random()*1000)
}
and read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Scoping_rules_2

Little tweaking of my image slider (adding transition animations)

Hi guys a created this image slider and i want to add transition animation, my desired transition is something like
this
Also here is my Javascript code:
let sliderImages = document.querySelectorAll(".slide"),
arrowLeft = document.querySelector("#arrow-left"),
arrowRight = document.querySelector("#arrow-right"),
current = 0;
// Clear all images
function reset() {
for (let i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = "none";
}
}
// Init slider
function startSlide() {
reset();
sliderImages[0].style.display = "block";
}
// Show prev
function slideLeft() {
reset();
sliderImages[current - 1].style.display = "block";
current--;
}
// Show next
function slideRight() {
reset();
sliderImages[current + 1].style.display = "block";
current++;
}
// Left arrow click
arrowLeft.addEventListener("click", function() {
if (current === 0) {
current = sliderImages.length;
}
slideLeft();
});
// Right arrow click
arrowRight.addEventListener("click", function() {
if (current === sliderImages.length - 1) {
current = -1;
}
slideRight();
});
startSlide();
And my html:
<div className="Slider">
<div id="arrow-left" className="arrow"></div>
<div id="slider">
<div className="slide slide1">
<div className="slide-content">
<span>My vám doručíme kvalitu<br/> na úrovni</span>
<button>Pozrieť viac</button>
</div>
</div>
<div className="slide slide1">
<div className="slide-content">
<span>Na tomto slide vám taktiez<br/> doručíme kvalitu</span>
<button>Pozrieť viac</button>
</div>
</div>
</div>
<div id="arrow-right" className="arrow"></div>
</div>
My javascript may be too long or inefficient but I just starting to get the hang of it also its inspired from youtube but it's work great minus the transition effect

Detecting if section is currently visible on scroll

I am trying to do a sort of navigation based on current section.
My code is as follows:
$(function() {
'use strict';
function setTitle(title) {
$('.overlay').text(title);
}
function removeTitle() {
$('.overlay').text('');
}
$(window).on('scroll', function() {
let windowScroll = $(window).scrollTop(),
sections = $('section[data-title]');
sections.each(function() {
let thisStart = $(this).offset().top,
thisHeight = $(this).outerHeight(true),
thisTitle = $(this).attr('data-title'),
thisEnd = thisHeight + thisStart;
console.log(`start: ${thisStart}, end: ${thisEnd}, scroll: ${windowScroll}`);
if(windowScroll >= thisStart && windowScroll < thisEnd) {
setTitle(thisTitle);
} else {
removeTitle();
}
});
});
});
HTML
<section class="section section-first"></section>
<section class="section section-what" data-title="First">
</section>
<section class="section section-cv" data-title="Secound">
</section>
<div class="overlay"></div>
Unfortunately, it works only with last .section. What can I do?
Please refer to my CodePen to see what I mean exactly: http://codepen.io/tomekbuszewski/pen/Xmovwq
Add return false; here:
if(windowScroll >= thisStart && windowScroll < thisEnd) {
setTitle(thisTitle);
return false; // <- add this
} else {
removeTitle();
}
That will break out of the each method and prevent the title from being removed once it's been set.
CodePen

Not directing to div id target when scroll

Have problems with firefox 33.1 my scroll to div is not directing to my target div id im using polymer core-scaffold as my navigation but its working fine using chrome
and i don't have any errors on my console
here's my script
<script>
var scaffold = document.getElementById('scaffold');
var menu = document.getElementById('menu');
menu.addEventListener('core-select', function(e) {
if (e.detail.isSelected) {
scrollToSection(e.detail.item.getAttribute('name'));
}
});
function scrollToSection(id) {
var section = document.getElementById(id);
if (section) {
scaffold.$.headerPanel.scroller.scrollTop = section.offsetTop;
}
}
</script>
here's my navigation code
<core-scaffold id="scaffold" responsiveWidth="640px">
<core-header-panel navigation flex mode="seamed">
<core-toolbar>Navigation</core-toolbar>
<core-menu id="menu">
<core-item name="drawerPanel" icon="home" label="Home"></core-item>
<core-item name="about" icon="account-circle" label="Who"></core-item>
<core-item name="works" icon="work" label="Works"></core-item>
<core-item name="skills-cont" icon="gesture" label="Skills" name="skills"></core-item>
<core-item name="contacts-cont" icon="settings-phone" label="Contacts"></core-item>
<core-item name="cart" icon="shopping-cart" label="D Shop"></core-item>
<core-item name="v8" icon="link" label="v8"></core-item>
<core-item name="v7" icon="link" label="v7"></core-item>
<core-item name="v6" icon="link" label="v6"></core-item>
</core-menu>
<div id="about">
<about-koh></about-koh>
</div>
<div id="works">
<works></works>
</div>
....
is it possible to change the offsetTop depends on browser like if in firefox i want it to offsetTop -75 then in chrome it will be offsetTop -10 ?
ok found out that the reason was my jquery script i had this script and it has a duplicate script with different class so to fix it i remove the duplicate script.
my old script reason i got problem
jQuery.noConflict();
jQuery(document).ready(function(){
var i = 0;
var posts = jQuery('.ab-effect').children();
function animateCircle() {
if (i % 2 === 0) {
jQuery(posts[i]).addClass('visible animated fadeInUp');
} else {
jQuery(posts[i]).addClass('visible animated fadeInDown');
}
i++;
if (i <= posts.length) {
startAnimation();
}
}
function startAnimation() {
setTimeout(function () {
animateCircle();}, 1000);
}
posts.addClass('hidden');
animateCircle(posts);
});
jQuery.noConflict();
jQuery(document).ready(function(){
var i = 0;
var posts = jQuery('.sk-effect').children();
function animateCircle() {
if (i % 2 === 0) {
jQuery(posts[i]).addClass('visible animated fadeInUp');
} else {
jQuery(posts[i]).addClass('visible animated fadeInDown');
}
i++;
if (i <= posts.length) {
startAnimation();
}
}
function startAnimation() {
setTimeout(function () {
animateCircle();}, 1000);
}
posts.addClass('hidden');
animateCircle(posts);
});
my new script that fix my problem - i just remove the duplicate script
jQuery.noConflict();
jQuery(document).ready(function(){
var i = 0;
var posts = jQuery('.ab-effect').children();
function animateCircle() {
if (i % 2 === 0) {
jQuery(posts[i]).addClass('visible animated fadeInUp');
} else {
jQuery(posts[i]).addClass('visible animated fadeInDown');
}
i++;
if (i <= posts.length) {
startAnimation();
}
}
function startAnimation() {
setTimeout(function () {
animateCircle();}, 1000);
}
posts.addClass('hidden');
animateCircle(posts);
});

Categories