how to make an animation only 1 time on scroll - javascript

This is my code: Fiddle
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.count').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false') {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count">5.6</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<p>Scroll up and then scroll down again</p>
<span class="count">5.6</span>
The problem is, the increasing number animation will run again, if i scroll up and scroll down again. What is the thing that i need to change to stop it? I tried a lot of things, but i am not good at Javascript.

You need to declare a global var as stopNow = 2 so your animation can only run twice and decrement it when animation runs.
var stopNow = 2;
Update the countEach function as follows
function countEach() {
$('.count').each(function() {
//also check stopNow != 0
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1; //decrement stopNow
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
Here's your updated working fiddle - https://jsfiddle.net/6w8ubh5y/7/

Use a global variable. Set it to false at the beginning. In the scroll event, check it and if it is still false, run the countEach() function then change the variable to true. Like this:
var stop = false;
countEach();
$(window).on('scroll', function(e) {
if(!stop){
countEach();
stop = true;
}
})

Change the event binding code from:
$(window).on('scroll', function(e) {
countEach()
})
to
$(window).on('scroll', countEach);
and change countEach function like this...
function countEach() {
$('.count').each(function() {
...
});
$(window).off('scroll', countEach); // add this line
}

Related

Number increase Jquery Animation stop at random number sometimes.

const ratingcount = document.querySelectorAll('.ratingcount');
const totalratingcounter = ratingcount.length;
var stopNow = totalratingcounter
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.ratingcount').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
//console.log($(this).text())
//console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1;
}/* else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}*/
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="ratingcount">7.4</span>
<span class="ratingcount">7.4</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<span class="ratingcount">7.4</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<span class="ratingcount">7.4</span>
Fiddle
Code Features:
It increase the number animation from 0 to given number in 1 second.
If the number is on screen, while loading the page, it do the animation
If the number is not on screen, while loading the page, it do the animation on scroll
All numbers do the animation only 1 time.
Problem: Sometimes, some numbers stop at random number (below the original number). The script do not work properly. I do not know, why it happens (maybe bcz of slow internet, or something else).
How can I optimize the code and fix the problem?

how to make an animation only 1 time on scroll

This is my code: fiddle
const ratingcount = document.querySelectorAll('.ratingcount');
const totalratingcounter = ratingcount.length;
var stopNow = totalratingcounter
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.ratingcount').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1;
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Follow my steps, Scroll down to middle
</h1>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>
<h1>NOW SCROLL UP AGAIN and then scroll down
</h1>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<h1>
Now see this is not working
</h1>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>
The problem.
const ratingcount = document.querySelectorAll('.ratingcount');
const totalratingcounter = ratingcount.length;
This code counts the number of ratingcount class.
And this code stops the animation after doing animation equal to the number of class
var stopNow = totalratingcounter
Fair enough right? But, the problem is, a number can do animation multiple times, and other number cannot do it.
Like: If i scroll down to a number in the middle, it will do the animation.
Then, instead of scrolling to the bottom, i scroll up and then again down.
Then the middle number do animation again, but the bottom number don't because of that.
Well, if I understood you correctly - You want each rating counter to be animated once, on its first show on screen. To achieve this, all you have to do is removing the else if() {...} from your function countEach(), As I did below:
const ratingcount = document.querySelectorAll('.ratingcount');
const totalratingcounter = ratingcount.length;
var stopNow = totalratingcounter
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.ratingcount').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
//console.log($(this).text())
//console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1;
}/* else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}*/
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Follow my steps, Scroll down to middle
</h1>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>
<h1>NOW SCROLL UP AGAIN and then scroll down
</h1>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<h1>
Now see this is not working
</h1>
<span class="ratingcount">5.6</span><br/>
<span class="ratingcount">5.6</span>

how to prevent bubbling event when use Turbolinks.visit(path)

I use aspnetmvcturbolinks in own project and I have reload page with
Turbolinks.visit(path) when user add text in input . but,when page changed I check this keyup event of input is fire more one and I add return false but not work .
$(document).on("ready page:load", function() {
$('input[name=keyword]').keyup(function (e) {
alert();
var $text = $(this).val();
if ($text.length > 1) {
$('html, body').animate({ scrollTop: 0 }, 600, function() {
Turbolinks.visit('#searchUrl' + '?keyword=' + $text);
});
}
if ($text.length == 0) {
Turbolinks.visit('#searchUrl');
}
return false;
});
$(document).on('change', 'select[name="order"]', function() {
Turbolinks.visit('#searchUrl');
});
$(document).on('change', 'select[name="count"]', function() {
Turbolinks.visit('#searchUrl');
});
});
what is solution?
thanks
Try to use
e.stopPropagation();
instead of
return false;
http://api.jquery.com/event.stoppropagation/
Try This,
if(e.stopPropagation)e.stopPropagation();
else e.cancelBubble=true; // where e is an event object
$('input[name=keyword]').keyup(function (e) {
alert();
var $text = $(this).val();
if ($text.length > 1) {
$('html, body').animate({ scrollTop: 0 }, 600, function() {
Turbolinks.visit('#searchUrl' + '?keyword=' + $text);
});
}
if ($text.length == 0) {
Turbolinks.visit('#searchUrl');
}
if(e.stopPropagation)e.stopPropagation();
else e.cancelBubble=true;
});

Page scrolls up after certain lines

I have problem when writing around 60 lines here in fiddle
then it start to scroll up !.
what im doing wrong there ? thanks.
I want to always stay scrolled down at bottom.
$chat = $('#chatarea');
$submit = $('#submit');
$input = $('#text')
ENTER = 13;
var addMessage = function(message) {
// create message element
$msg = $('<div>', {class: 'message hidden-message', text: message})
if($input.val().length > 0){
// append element
$chat.append($msg) ;
}
else
{
return false;}
$msg.hide().removeClass('hidden-message') ;
$msg.slideDown(function(){
// animate scroll to bottom
$chat.animate({ scrollTop: $chat.height() })
});
};
$input.on('keydown', function(e){
if(e.keyCode === 13 && $input.val().length < 1 ){
return false;
}
});
$input.on('keyup', function(e){
if(e.keyCode == 13 && $input.val().length > 1 ) {addMessage($input.val());
$input.val('');
}
else if(e.keyCode == 13 && $input.val().length == 1){
$input.val('');
e.preventDefault();
return false;}else{}
});
$submit.on('click', function(){
if($input.val().length > 1) {
addMessage($input[0].value);
$input.val('');
}
});
The Problem:
.holder has a height of 1000px and .chatarea inside it has a height of 90%, so in your script $chat.height() always returns 900, so after 60 lines or so, whenever there's an input it scrolls to 900px and stays there.
Solution:
Use this:
$chat.animate({ scrollTop: $chat.prop("scrollHeight") - $chat.height() })
Or a faster animation:
$chat.animate({ scrollTop: $chat.prop("scrollHeight") - $chat.height() }, 25)
Instead of this:
$chat.animate({ scrollTop: $chat.height() })
Demo http://jsfiddle.net/MYPgE/8/
Problem is within $msg.slideDown function, just comment out $chat.animate({ scrollTop: $chat.height() }) and put this code into the $submit.on click function
$(function () {
$("#chatarea").animate({
scrollTop: $('#chatarea').get(0).scrollHeight}, 1000);});
}
fiddle: http://jsfiddle.net/MYPgE/6/

Expand a div element multiple times

I have a searchbar and the results should be shown on google maps. I want to expand and collapse this map so more results will be visible. But I dont want a normal toggle function.
I want a multiple click action:
First click: Div/Map gets 100px higher
Second click: Div/Map gets another 100px higher
Third click: Div/Map gets 100px smaller,
Fourth click: Div/Map gets another 100px smaller and returns to its original height.
Fifth click: All the previous action should be repeated.
This is what I've got up till now, but After my fourth click nothing happens anymore:
$(function(){
var hits = [0];
$('.kaart-uitklappen').click(function(){...
Fiddle Demo
You don't need as many animate calls, as you basically just change the height modifier. As there are four states essentially (two for going up, two for going down), you need to reset the counter accordingly (i.e., when it reaches 4) - that's done easily with modulo operator.
$(function(){
var hits = -1;
$('.kaart-uitklappen').click(function(){
hits = (hits+1) % 4;
var modifier = hits > 1 ? '-' : '+';
$('#header').animate({height: modifier + '=100px' }, 300);
return false;
});
});
JSFiddle.
You need to make sure your value does not exceed 3, or nothing will happen on subsequent clicks. Also, you should start with your value equal to 0, not [0].
Here is some simplified code with these ideas incorperated: http://jsfiddle.net/XZ7mW/16/
var hits = 0;
$('.kaart-uitklappen').click(function(){
if (hits < 2)
$("#header").animate({'height':'+=100px' }, 300);
else
$("#header").animate({'height':'-=100px' }, 300);
hits = (hits + 1) % 4;
return false;
});
change from hits == number to hits%4 == number
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits%4 == 0) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
}
if (hits%4 == 1) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
}
if (hits%4 == 2) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
}
if (hits%4 == 3) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
}
hits++;
return false;
});
});
You need to reset your var to 0 once you get to 3 -
if (hits == 3)
{
$("#header").animate({'height':'-=100px' }, 300, function() {});
hits = -1;
}
You also shouldn't be using an array to store hits.
hits = [0]
should be
hits = 0;
http://jsfiddle.net/XZ7mW/10/
On the last if type in this
$("#header").animate({'height': '-=100px'}, 300, function () {});
hits = 0;//make hits 0
return;//return so it doesnt add to hits
}
DEMO
JAVASCRIPT :
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits == 0) {
$("#header").animate({
'height': '+=100px'
}, 300);
}
else if (hits == 1) {
$("#header").animate({
'height': '+=100px'
}, 300);
}
else if (hits == 2) {
$("#header").animate({
'height': '-=100px'
}, 300);
}
else {
$("#header").animate({
'height': '-=100px'
}, 300);
hits = 0;
return false;
}
hits++;
return false;
});
});
Fiddle : http://jsfiddle.net/XZ7mW/12/
Here you go :
JSFiddle
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits == 0) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
hits++;
}
else if (hits == 1) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
hits++;
}
else if (hits == 2) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
hits++;
}
else if (hits == 3) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
hits = 0;
}
return false;
});
});
You need to reset hits when it reaches 3
Assuming you want this to expand, contract and then re-expand:
var hits = [0]; should be var hits = 0; and you will need to test for hits > 3 and set it back to 0;
or use modulus arithmetic in your conditions:
http://jsfiddle.net/XZ7mW/19/
$(function(){
var hits = 0;
$('.kaart-uitklappen').click(function(){
if (hits % 4 == 0) {
$("#header").animate({'height':'+=100px' }, 300, function() {});
}
if (hits % 4 == 1) {
$("#header").animate({'height':'+=100px' }, 300, function() {});
}
if (hits % 4 == 2) {
$("#header").animate({'height':'-=100px' }, 300, function() {});
}
if (hits % 4 == 3) {
$("#header").animate({'height':'-=100px' }, 300, function() {});
}
hits++;
return false;
});
});
Here's how I would do it:
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits < 2)
$("#header").animate({'height': '+=100px'}, 300);
else
$("#header").animate({'height': '-=100px'}, 300);
if (++hits == 4)
hits = 0;
return false;
});
http://jsfiddle.net/KX7aq/
Add this at the end to reset the counter:
if(hits==4) {
hits=0;
}
http://jsfiddle.net/XZ7mW/7/
Can be something like this?
var direction = "open";
$('.kaart-uitklappen-button').click(function(){
if (direction == "open"){
$('.kaart-uitklappen').height($('.kaart-uitklappen').height()+100)
if ($('.kaart-uitklappen').height() >= 200){
direction = "close";
}
}else{
$('.kaart-uitklappen').height($('.kaart-uitklappen').height()-100)
if ($('.kaart-uitklappen').height() <= 0){
direction = "open";
}
}
I use kaart-uitklappen-button because you can't click the container if it is closed...

Categories