JS counter when scroll to a div stop counting - javascript

I want to make a counter on javascript that when you go to certain div, start counting and when you reach the specified number it stops, and if I continue scrolling, the counter no longer keep counting
I have made a Pen with the idea, but when I continue scrolling the counter do not stop, and start to count down, and then stop when reach a low number.
Any idea to make this work?
Thanks in advance.
HTML
<!-- Counter section -->
<div id="counter" class="Wrapper-counter">
<!-- Counter_item -->
<div class="Counter_item">
<h3 class="Counter_h3 right">
<span class="count">
123
</span>
</h3>
<p class="Counter_paragraph right">
<strong>Lorem ipsum</strong>
</p>
</div>
<!-- /Counter_item -->
<!-- Counter_item -->
<div class="Counter_item">
<h3 class="Counter_h3 left">
<span class="count">
123
</span>
</h3>
<p class="Counter_paragraph left">
<strong>Lorem ipsum</strong>
</p>
</div>
<!-- /Counter_item -->
</div>
<!-- /Counter section -->
JS
$(window).on('scroll', function() {
var div_counter = window.pageYOffset;
var scroll_pos_test = $('#counter').offset().top - window.innerHeight; // set to whatever you want it to be
if(div_counter < scroll_pos_test) {
//do stuff
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 3000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
});
codepen here

I didn't understand your code, but I created an example of what you are looking for which might give you a new perspective of how to tackle this problem in an easier way. Check out the working example on CODEPEN.
HTML
<div class="container">
<p data-counter="100">100</p>
</div>
CSS
p {
font-size: 3em;
position: fixed;
color: blue;
}
.container {
position: relative;
height: 700px;
background: #ccc;
}
JS
$(document).ready(function() {
var topCount = 100;
var maxCount = 50;
var startCount = 200;
var endCount = 400;
var currCount = 0;
$(window).scroll(function() {
if (($(window).scrollTop() >= startCount) && ($(window).scrollTop() <= endCount)) {
currCount = Math.floor(maxCount + (maxCount - topCount) * ($(window).scrollTop() - endCount) / (endCount - startCount));
$("p").attr("data-counter",currCount).text(currCount);
}
});
});
It should be pretty straight-forward. I don't have a resetting mechanism since I don't know how you want to do it or if you want to have it at all. but it is easy to add any modification

thanks for the code but it is not what I was looking; I solved the problem by adding the plugin INVIEW JQUERY and the following script, thanks anyway
CODEPEN DEMO
$('#counter').bind('inview', function(event, visible, visiblePartX, visiblePartY) {
if (visible) {
$(this).find('.count').each(function () {
var $this = $(this);
$({ Counter: 0 }).animate({ Counter: $this.text() }, {
duration: 2000,
easing: 'swing',
step: function () {
$this.text(Math.ceil(this.Counter));
}
});
});
$(this).unbind('inview');
}
});

Related

Stopping all other animations using no selector in $.animate with step()?

I'm animating objects using arrays in my selector which I am stuck using for a specific reason in another SO post I made.
How am I able to stop other animations that have been started from arbitrary array values? E.g: $({ x: 0 }).animate({
For example:
$({ x: 0 }).animate({
x: 500
}, {
easing: 'linear',
duration: 15000,
step: function(now, fx) {
// $(this).stop();
var current_styles = $(selector).attr('style'),
current_styles = string = current_styles.split(" ");
var x = parseFloat(current_styles[1].replace('px', '').replace(';', ''));
if ('x' === fx.prop) {
x = now;
}
$(selector).attr({ style: 'margin-left: ' + x + 'px;' });
},
complete: function() {
//
}
});
HTML:
<div class="row row_1"><button data-id="1">GO</button><div class="box" style="margin-left: 0;"></div></div>
<div class="row row_2"><button data-id="2">GO</button><div class="box" style="margin-left: 0;"></div></div>
<div class="row row_3"><button data-id="3">GO</button><div class="box" style="margin-left: 0;"></div></div>
<div class="row row_4"><button data-id="4">GO</button><div class="box" style="margin-left: 0;"></div></div>
<div class="row row_5"><button data-id="5">GO</button><div class="box" style="margin-left: 0;"></div></div>
<div class="row row_6"><button data-id="6">GO</button><div class="box" style="margin-left: 0;"></div></div>
CSS:
.row {
background-color: green;
margin-bottom: 1px;
width: 600px;
}
.box {
background-color: red;
height: 20px;
width: 20px;
display: inline-block;
}
button {
float: left;
}
I want to stop all other animations when I start this one. However, I cannot use $(selector).stop(); as it does not work.
JSFiddle & gif of issue:
JSFiddle of desired results (Using incorrect formatting for my purpose):
You can stop an animation from within a step() using $(this).stop(); but that only stops the one animation you are inside.
Basically, I need to be able to stop all other animations and then continue with the animation that was just started. The JS itself works exactly as intended, I just need to stop the old animations in their tracks as the new one starts.
It's not clear to me of an elegant nor easy way to do this when using:
$({ x: 0 }).animate({
Thank you for taking the time to consider my question
Store the previous started animation in a variable so you can access it (to retrieve the current value and to stop it):
var prevAnimation;
function runAnimation(selector) {
var start = 0;
if (prevAnimation) {
start = prevAnimation.get(0).x;
prevAnimation.stop();
}
prevAnimation = $({ x: start }).animate({
x: 500
}, {
easing: 'linear',
// And so on
Updated fiddle: https://jsfiddle.net/7vk9d2te/9/
-- Update --
If your animation is just about the margin-left, you could really simplify your code by removing the step function and letting jQuery do the magic with
function runAnimation(selector) {
var start = 0;
if (prevAnimation) {
start = parseFloat(prevAnimation.css('margin-left'));
prevAnimation.stop();
}
prevAnimation = $(selector)
.css('margin-left', start + 'px')
.animate({ 'margin-left': 500 }, {
easing: 'linear',
duration: 15000,
});
}
Fiddle: https://jsfiddle.net/7vk9d2te/10/

Make sticky/fixed element stop at footer

I'm trying to make the side bar stop following the user's scroll once it hits the footer. Right now I set the z-index to -2 so that it goes behind the footer, but it sticks out a tiny bit.
JavaScript
$(document).ready(function () {
var floatingDiv = $('#side_bar');
var floatingDivPosition = floatingDiv.position();
$(window).scroll(function (){
var scrollBarPosition = $(window).scrollTop();
if(scrollBarPosition >= floatingDivPosition.top) {
floatingDiv.css({
'position': 'fixed',
'top': 55,
'width': '18.6676%',
'z-index': -2
});
}
else{
floatingDiv.css({
'position': 'relative',
'top': 0,
'width': '79.4392%'
});
}
});
});
HTML
<div id="content">
<div id="col_1">
<div id="side_bar">
<h4 id="cater_to">We cater to</h4>
<button class="side_bar_btns">Contractor</button>
<button class="side_bar_btns">Wood/Sport Floors</button>
<button class="side_bar_btns">Grocery/Commercial</button>
<button class="side_bar_btns">Education</button>
<h4 id="simplicity">Simplicity</h4>
<div id="all_systems_side_bar">
<img src="images/all_systems_logo.png" alt="All Systems Maintenance logo. Links to more about All Systems Maintenance." width="100%">
</div><!-- all systems side bar -->
</div><!-- side_bar -->
</div><!-- col_1 -->
<div id="col_2">
//// bunch of stuff here
</div><!-- col_2 -->
<div class="clear"></div>
</div><!-- content -->
<footer>
/// bunch of stuff here
</footer>
CSS
#col_1 {
float:left;
margin-top:44px;
width:23.4994%;
margin-left:3.9531%;
}
#side_bar {
background:#003768;
min-height:665px;
width:79.4392%;
border-radius:20px;
box-shadow: 10px 10px 5px #888;
}
#col_2 {
float:right;
margin-top:44px;
width:68.5944%;
margin-right:3.9531%;
}
footer {
background-image:url(../images/foot_background.gif);
background-repeat:no-repeat;
background-size:cover;
}
The footer background is almost the same height as the screen (about 824px when I inspect it with Chrome).
Found this gem on Youtube at https://www.youtube.com/watch?v=5s0L6dCVevk and changed it slightly to come up with the following, which works.
$(function() {
if ($('#side_bar').length) {
var el = $('#side_bar');
var stickyTop = $('#side_bar').offset().top;
var stickyHeight = $('#side_bar').height();
$(window).scroll(function(){
var limit = $('footer').offset().top - stickyHeight - 20;
var windowTop = $(window).scrollTop();
if (stickyTop < windowTop) {
el.css({
position: 'fixed',
top: 55,
width: '18.6676%'
});
} else {
el.css({
position: 'static',
width: '79.4392%'
});
}
if (limit < windowTop) {
var diff = limit - windowTop;
el.css({
top: diff
});
}
});
}
});

Flexslider fullscreen is not centered in mobile

I have this fullscreen background that I'm using and it works correctly on my laptop and big screens. The problem is when I enter the website from a mobile device. The background image (and the buttons above it) move to the side. I do not know why is this. I think it has to be with the bootstrap.min.
The HTML:
<!-- Intro Section -->
<section id="intro">
<!-- Hero Slider Section -->
<div class="flexslider fullscreen-carousel hero-slider-1 ">
<ul class="slides">
<!--Slide-->
<li data-slide="dark-slide">
<div class="slide-bg-image overlay-light dark-bg parallax" data-background-img="images/connexion_background.jpg">
<div class="js-Slide-fullscreen-height container">
<div class="intro-content">
<div class="intro-content-inner">
<br />
<div><a class="btn btn-md btn-white" href="contact.php">Request a Quote</a><span class="btn-space-10"></span><a class="btn btn-md btn-white " href="research-solutions.html">View Our Solutions</a></div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<!-- End Hero Slider Section -->
</section>
<div class="clearfix"></div>
<!-- End Intro Section -->
The JS:
var pageSection = $('.slide-bg-image, .bg-image');
pageSection.each(function (indx) {
if ($(this).attr("data-background-img")) {
$(this).css("background-image", "url(" + $(this).data("background-img") + ")");
}
});
function fullScreenSlider() {
if ($('.fullscreen-carousel').length > 0) {
$('.fullscreen-carousel').flexslider({
animation: "slide",
// startAt: 0,
animationSpeed: 700,
animationLoop: true,
slideshow: true,
easing: "swing",
controlNav: false,
before: function (slider) {
//Slide Caption Animate
$('.fullscreen-carousel .intro-content-inner').fadeOut().animate({ top: '80px' }, { queue: false, easing: 'easeOutQuad', duration: 700 });
slider.slides.eq(slider.currentSlide).delay(400);
slider.slides.eq(slider.animatingTo).delay(400);
},
after: function (slider) {
//Slide Caption Animate
$('.fullscreen-carousel .flex-active-slide').find('.intro-content-inner').fadeIn(2000).animate({ top: '0' }, { queue: false, easing: 'easeOutQuad', duration: 1200 });
// Header Dark Light
headerDarkLight_with_flexslider();
},
start: function (slider) {
$('body').removeClass('loading');
// Header Dark Light
headerDarkLight_with_flexslider();
},
useCSS: true,
});
};
// Header Dark Light
function headerDarkLight_with_flexslider() {
var color = $('.fullscreen-carousel').find('li.flex-active-slide').attr('data-slide');
if (color == 'dark-slide') {
$('#header').addClass('header').removeClass('header-light');
$('#header').removeClass('header-default');
}
if (color == 'light-slide') {
$('#header').addClass('header-light').removeClass('header-dark');
$('#header').removeClass('header-default');
}
if (color == 'default-slide') {
$('#header').removeClass('header-dark');
$('#header').removeClass('header-light');
$('#header').addClass('header');
}
};
// "fullscreen-carousel" height
fullScreenCarousel();
function fullScreenCarousel() {
var windowWidth = $(window).width();
var windowHeight = $(window).height();
if ($(window).width() > 767) {
$('.hero-slider-1 .slides .js-Slide-fullscreen-height').css("height", windowHeight);
}
else {
$('.hero-slider-1 .slides .js-Slide-fullscreen-height').css("height", '400px');
}
};
$(window).resize(function () {
fullScreenCarousel();
});
};
This is the result in mobile:
The buttons and the background image are moved to the right. They are not centered and the background picture repeat itself.
I can see this on the development tool of Mozilla:
Any help would be appreciated.
Thank you.
center the images in your slides add this in your css
.flexslider img { margin: 0 auto; }
OR
.flexslider .slides > li{
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
can you try to add following css at last of the css document
.flexslider ul.slides {
padding: 0 !important;
}
Your flex slider left position is not right , You can simply fix this with left property, try with the below code
.fullscreen-carousel .slides li {
height: 100%;
left: -40px; /* newly added */
overflow: hidden;
position: relative;
}
can you try this also , remove the left:-40px and add this jquery to the page
$(window).load(function() {
$('.flexslider').flexslider();
$(window).trigger('resize');
});

jQuery - change class with timer

I have a CSS slider that I'm using with a bit of jQuery to change the class of the list item on click. I would also like to have the slider on a timer so every 5s it auto executes the removeClass of the selected list item and adds "selected" class to the next list item in the list if there is no user interaction.
At the same time as changing the class on the li element it needs to change the #slide_images transform to what it needs to be (0px,1100px,2200px,3300px or 4400px) etc.
If it does have user interaction via them selecting a link for a slide then the timer should stop until page reload.
Here is the HTML:
<div id="slide_container">
<div style="transform: translateX(0px);" id="slide_images">
<div class="slide1">
<img src="http://example.com/1.jpg">
<div class="slide-content1">
slide1content
</div>
</div>
<div class="slide2">
<img src="http://example.com/2.jpg">
<div class="slide-content2">
slide1content
</div>
</div>
<div class="slide3">
<img src="http://example.com/3.jpg">
<div class="slide-content3">
slide1content
</div>
</div>
</div>
</div>
Here is the CSS:
.slide-content1,.slide-content2,.slide-content3,.slide-content4,.slide-content5{position:absolute;top:20px;left:0;padding:110px 0 0;width:1100px;color:#fff}
.slide-content2{left:1100px}
.slide-content3{left:2200px}
.slide-content4{left:3300px}
.slide-content5{left:4400px}
#slide_container{width:1100px;height:580px;overflow:hidden;margin:0 auto}
#slide_images{width:5500px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out}
#slide_images img{padding:0;margin:0;float:left;border:none}
Here is the script:
jQuery(document).ready(function($) {
$(document).ready(function() {
$('.slidenav').on('click', 'li', function(){
$("#slide_images").css("transform","translateX("+$(this).index() * -1100+"px)");
$(".slidenav li").removeClass("selected");
$(this).addClass("selected");
});
});
});
Thanks for any help :).
I have an example with a working rotator. It will rotate every 5 seconds when there is no user interaction. When you click on a item, the timer resets to 0 and continues after 5 seconds with rotation.
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="script.js"></script>
</head>
<body>
<ul class="slidenav">
<li>slide1</li>
<li>slide2</li>
<li>slide3</li>
</ul>
</body>
</html>
CSS:
ul.slidenav li {
color: #000;
}
ul.slidenav li.selected {
color: red;
}
JS:
$(document).ready(function() {
var slides = $(".slidenav li");
//Init slide 1
slideTo(slides[0]);
var slideIndex = 0;
var slideTime = animate();
$(".slidenav li").click(function() {
//Reset the interval to 0 and start it again
clearInterval(slideTime);
slideTime = animate();
var selectedIndex = $(this).index();
var slide = slides[selectedIndex];
slideTo(slide);
});
function slideTo(slide) {
$(".slidenav li").removeClass("selected");
$(slide).addClass("selected");
slideIndex = jQuery(slide).index();
}
function animate() {
return setInterval(function() {
var slide = slides[slideIndex];
slideTo(slide)
slideIndex++;
if (slideIndex == slides.length) {
slideIndex = 0;
}
}, 5000);
}
});
Plunker: https://plnkr.co/edit/ah1CTexSjnROAEPMAitk?p=preview
To execute something with a delay, you can use setTimeout().
You can use a delayTime variable and then modify it on user click event.
A quick approach to the solution would be
var delayTime = 5000; // milliseconds
$(function() {
$('.slidenav').click(function () {
setTimeout(function () {
$('.slidenav li').removeClass('newClass');
}, delayTime);
});
$('.clickedLink').click(function () {
delayTime = 0;
});
});
Notice, I also shortened the code a little bit: $(ready) and .on('click')
Take a look at this codesnippet.
$(document).ready(function(){
$(".slider li:first-child").addClass("active");
setTimeout(autoAddClass, 1000);
});
function autoAddClass(){
var next = $(".active").removeClass("active").next();
if(next.length)
$(next).addClass('active');
else
$('.slider li:first-child').addClass('active');
setTimeout(autoAddClass, 1000);
}
You should start by setting an interval, and once your user does his interaction, you can clear that interval using clearInterval. Here is a pseudo code:
var interval = setInteval(function(){
// do whatever here...
}, 5000);
$('yourSelector').click(function(){
clearInterval(interval);
// do whatever....
});

jquery slider with controls and automatic scrolling

Basically I am just trying to do random jQuery stuff for educational purpose, and here is my very simple slider. I want it to work automatically and also with controls (little arrows to scroll to next/previous slider). The only problem that I have right now is that when you press the arrow, the function that automatically switches slides every 5 seconds is still counting these 5000 ms, so the next slide appears faster then desired. What I want is to make those arrows reset the timer, so you press the arrow -> next slide appears -> only after 5 seconds later the slide switches again.
Sorry for sloppy explanation, hope I made it clear enough.
Here's the jsfiddle: http://jsfiddle.net/cA9aW/
and here is the code
HTML
<body>
<div id="wrapper">
<header>
<h1>Simplest Sliding Image Slider</h1>
</header>
<div id="content">
<div id="slider_container">
<div id="slider">
<div class="slides" id="slide1">
<img src="http://s2.postimg.org/5uxqi0mgl/cats1.jpg" alt="" />
</div>
<div class="slides" id="slide2">
<img src="http://s2.postimg.org/66f6us2wl/cats2.jpg" alt="" />
</div>
<div class="slides" id="slide3">
<img src="http://s2.postimg.org/ai3sjs9th/cats3.jpg" alt="" />
</div>
</div>
</div>
</div>
<footer></footer>
</div>
</body>
JS
jQuery(document).ready(function($) {
// start slider function
startSlider();
// set width and step variables and add active class to first slider
var slideWidth = $('.slides').width();
$('#slide1').addClass('slides active');
// actual function
function startSlider() {
looper = setInterval(function() {
// remove and add class active
$('.active').removeClass('active').next().addClass('active');
// animation expression
$('.active').animate({'left': '-=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '-=' + (slideWidth) + 'px'}, 500);
// return to first slide after the last one
if($('.active').length == 0) {
$('#slide1').addClass('active');
$('.slides').animate({'left': 0}, 500);
}
}, 5000); // interval
// adding controls
$('.slides').append("<div class='controls'><a class='control_left' href='#'></a><a class='control_right' href='#'></a></div>");
// remove unnecessary controlls on first and last slides
$('.slides:nth-child(1) a.control_left').remove();
$(".slides:nth-child(" + $('.slides').length + ") a.control_right").remove();
// add functionality to controls
$('.control_left').on('click', function() {
$('.active').removeClass('active').prev().addClass('active');
$('.active').animate({'left': '+=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '+=' + (slideWidth) + 'px'}, 500);
});
$('.control_right').on('click', function() {
$('.active').removeClass('active').next().addClass('active');
$('.active').animate({'left': '-=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '-=' + (slideWidth) + 'px'}, 500);
});
}
});
Thx a lot in advance
Slideshow with prev/next buttons, autoslide, pause on hover
Instead of jQuery's .animate() and animating the left CSS property, use the GPU accelerated CSS transform: translateX for the animation on a common slides wrapper element
$(".SlideShow").each((i, EL) => {
const
$parent = $(EL),
$slides = $(".SlideShow-slides", EL),
$item = $(".SlideShow-item", EL),
$prevNext = $(".SlideShow-btn", EL),
tot = $item.length,
mod = (n, m) => ((n % m) + m) % m;
let
c = 0,
itv;
const prev = () => {c = mod(--c, tot); anim();};
const next = () => {c = mod(++c, tot); anim();};
const anim = () => $slides.css({transform: `translateX(-${c * 100}%)`});
const stop = () => clearInterval(itv);
const play = () => itv = setInterval(next, 4000);
$prevNext.on("click", (ev) => $(ev.currentTarget).is(".next") ? next() : prev());
$parent.hover(stop, play);
play(); // start
});
.SlideShow {
position: relative;
overflow: hidden;
width: 100%;
height: 180px;
}
.SlideShow-slides {
display: flex;
flex-flow: row-nowrap;
height: 100%;
width: 100%;
transition: transform 0.7s; /* Animation duration here */
}
.SlideShow-item {
min-width: 100%;
}
.SlideShow-item>img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.SlideShow-btn {
position: absolute;
top: 0;
z-index: 1;
width: 50px;
height: 100%;
background: rgba(255, 255, 255, 0.5);
opacity: 0.5;
border: 0;
cursor: pointer;
}
.SlideShow-btn:hover {
opacity: 1;
}
.SlideShow-btn.next {
right: 0px;
}
<div class="SlideShow">
<div class="SlideShow-slides">
<div class="SlideShow-item"><img src="http://placehold.it/600x400/0bf?text=A" alt=""></div>
<div class="SlideShow-item"><img src="http://placehold.it/600x400/fb0?text=B" alt=""></div>
<div class="SlideShow-item"><img src="http://placehold.it/600x400/0fb?text=C" alt=""></div>
</div>
<button type="button" class="SlideShow-btn prev"></button>
<button type="button" class="SlideShow-btn next"></button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
What you need to do it to clear the interval in the button clicks and start interval again.
function resetInterval(){ //add this method which wil reset the timer
window.clearInterval(looper); //clear current interval
looper = setInterval(autoSlide, 5000); //start auto slide again.
}
function autoSlide(){ //move this to a function from being anonymous
// remove and add class active
$('.active').removeClass('active').next().addClass('active');
// animation expression
$('.active').animate({
'left': '-=' + (slideWidth) + 'px'
}, 500);
$('.active').siblings().animate({
'left': '-=' + (slideWidth) + 'px'
}, 500);
// return to first slide after the last one
if ($('.active').length === 0) {
$('#slide1').addClass('active');
$('.slides').animate({
'left': 0
}, 500);
}
}
and
$('.control_left').on('click', function () {
resetInterval(); //reset it
....
$('.control_right').on('click', function () {
resetInterval(); //reset it
....
Demo

Categories

Resources