I have this jQuery code that triggers a counter from 0 to 1750. But, this counter is at the bottom of my page, and if you don't scroll to it quickly enough you miss the counter animation. Is there a way to trigger this to run only once you've hit the element in the window?
// Counter
$(document).ready(function() {
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 12000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
});
Try something like this, check your window top position and if is higher or equal of your target element and less the window height, then do your count animation.
HTML
<div class="wrapper-count">
<ul>
<li class="count">0</li>
<li class="count">0</li>
<li class="count">0</li>
</ul>
</div>
JS
$(document).ready(function(){
$(function(){
$(window).on("scroll", function(){
var win_height = $(this).height();
var win_pos = $(this).scrollTop();
var top_pos = $(".wrapper-count").position().top;
if(win_pos >= top_pos - win_height){
// here goes your count logic
}
});
});
});
Related
I want the number to count up to its designated value and stay there, but because the function gets called every time the page is being scrolled below a certain height, then it goes back to 1.
The solution would be to make it call the function only once when the page has been scrolled to below the certain height.
Ive tried placing the .one() method several places but that didn't help
http://jsfiddle.net/d7vKd/1543/
$(document).on('scroll', function() {
if ($(this).scrollTop() >= $("#mydiv").position().top) {
window.randomize = function() {
$('.radial-progress1').attr('data-progress', Math.floor(94));
};
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 6000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
setTimeout(window.randomize, 200);
}
})
You should unbind your scroll event once the callback has met its demands:
$(document).on('scroll.someName', function(){
var isPassedPos = $(this).scrollTop() >= $("#mydiv").position().top;
if( isPassedPos ){
$(document).off('scroll.someName') // <-------------- remove the event listener
window.randomize = function() {
$('.radial-progress1').attr('data-progress', Math.floor(94));
};
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 6000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
setTimeout(window.randomize, 200);
}
})
I am using this jQuery script that automatically scrolls a div horizontally based on the width of the div. But I need it to scroll to the very end of the div based on the end of the content that is inside of the div. The div has an 'overflow-y: scroll' attribute, so I'd like it to scroll through all of the content until it reaches the end.
This is the script I'm currently using:
function animatethis(targetElement, speed) {
var width = $(targetElement).width();
$(targetElement).animate({ marginLeft: "-="+width},
{
duration: speed,
complete: function ()
{
targetElement.animate({ marginLeft: "+="+width },
{
duration: speed,
complete: function ()
{
animatethis(targetElement, speed);
}
});
}
});
};
animatethis($('#q1'), 5000);
It does scroll, but it's not scrolling to the very end of the content inside of the div. Here is a jFiddle that shows what I mean:
http://jsfiddle.net/rKu6Y/535/
How can I get it to auto-scroll horizontally to the END of the content rather than just the width of the div?
I hope this all makes sense. Thanks.
You can animate the scrollLeft property, using scrollWidth and clientWidth:
function animatethis(targetElement, speed) {
var scrollWidth = $(targetElement).get(0).scrollWidth;
var clientWidth = $(targetElement).get(0).clientWidth;
$(targetElement).animate({ scrollLeft: scrollWidth - clientWidth },
{
duration: speed,
complete: function () {
targetElement.animate({ scrollLeft: 0 },
{
duration: speed,
complete: function () {
animatethis(targetElement, speed);
}
});
}
});
};
animatethis($('#q1'), 5000);
The result can be seen in this jsfiddle.
I have the below html
<ul>
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</ul>
<div id="vis"></div>
<style>li {position: relative;}</style>
On click I want to move the clicked item to the left 50px then slide it up then output how many list items are now visible in my div with the id vis.
If I do the below it counts 1 to many because the animation hasn't completed when I add the length see fiddle.
<script>
$("li").on("click", function () {
$(this).animate({
"left": "+=50px"
}).slideUp(300);
var visNum = $('li:visible').length;
$('#vis').text(visNum);
});
</script>
If I just do hide() I get the expected output in the vis div but don't get the animation I require. See Fiddle
<script>
$("li").on("click", function () {
$(this).hide();
var visNum = $('li:visible').length;
$('#vis').text(visNum);
});
</script>
and if I try a callback, I get a similar result to my first attempt. See Fiddle
<script>
$("li").on("click", function () {
$(this).animate({
left: "+=50px",
}, 300, function() {
$(this).slideUp(300);
var visNum = $('li:visible').length;
$('#vis').text(visNum);
});
});
</script>
What is the best way to do this so that after you click an item it animates left, slides up then outputs the remaining visible list items?
slideUp has a complete() callback. http://api.jquery.com/slideup/
<script>
$("li").on("click", function () {
$(this).animate({
"left": "+=50px"
}).slideUp(300, function(){
var visNum = $('li:visible').length;
$('#vis').text(visNum);
});
});
</script>
And for completion... http://jsfiddle.net/fjqmj/4/
Try this :
While taking visible li, just filter the current one with .not(this). This may not be the best approach but it works for you.
$("li").on("click", function () {
$(this).animate({
"left": "+=50px"
}).slideUp(300);
var visNum = $('li:visible').not(this).length;
$('#vis').text(visNum);
});
Demo
I've implemented a scroll left for navigating to sections that works perfectly.
Now I want to add anchors within a section so if you click on them they scroll down on a page to other anchors, smoothly. I'm trying to add the functionality within my existing function but to no avail.
I'm using "jquery.easing.pack.js".
In the original one I have the HTML and JS looks like this:
<!-- scroll left to sections -->
<section id="1" class="section"></section>
<section id="2" class="section"></section>
<section id="3" class="section"></section>
<script type="text/javascript">
$(function() {
var $sections = $('section.section');
$sections.each(function() {
var $section = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$scrollElement.stop().animate({
scrollLeft: $section.offset().left
}, 1200, 'easeOutCubic', function() {
window.location.hash = hash;
});
event.preventDefault();
});
});
});
</script>
Now I have:
<!-- scroll left to sections -->
<section id="1" class="section">
<a class="scroll-down" href="#bottom-div">scroll down</a><!-- scroll down to div -->
<div id="bottom-div>here we go</div>
</section>
<section id="2" class="section"></section>
<section id="3" class="section"></section>
At the moment if I click on the "scroll down" anchor it will go to the bottom-div but not smoothly. So I've tried adding another function like this but it's not working.. any ideas how to make it work and if possible with my existing function?
$(function() {
var $bottomdivs = $('.scroll-down');
$bottomdivs.each(function() {
var $bottomdiv = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$scrollElement.stop().animate({
scrollTop: $bottomdiv.offset().top-100
}, 1200, 'easeOutCubic', function() {
window.location.hash = hash;
});
event.preventDefault();
});
});
});
By setting the hash I think you are invoking the standard anchor link functionality to jump to the section. Try handling the scroll yourself like this:
var $sections = $('section.section');
$sections.each(function() {
var $section = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$('body, html').animate({
scrollLeft: $section.offset().left
}, {queue:false, duration: 1200, easing: 'swing'});
$('body, html').animate({
scrollTop: $section.offset().top
}, {queue:false, duration: 1200, easing: 'swing', done: function () {
window.location.hash = hash;
}
});
});
event.preventDefault();
});
I have put together a fiddle for you here: http://jsfiddle.net/rjE4s/
I am not sure what $scrollElement was so I have removed that from my example. Also I have changed your custom easing as I didn't have the easing pack installed. You can just change that back. Finally, I queued the animations so the left and top scroll at the same time, but you just set:
queue: true
in the animation options and it will animate the left and then the top like in your original function. Not sure if you wanted this or not.
I used the following javascript:
$('.slide-content #show-effect-1').hover(function(){
$(this).next().stop(true, true).fadeIn({ duration: _duration, queue: false }).css('display', 'none').show('slide', { direction: "down" }, _duration);
},
function() {
$(this).next().stop(true, true).fadeOut({ duration: _duration, queue: false }).hide('slide', { direction: "down" }, _duration);
});
What should happen is:
mouseenter the button --> content show
mouseout the button --> content hide
Question: when mouseout on the button is faster than the effect time of mouseenter, the content will be hidden and not displayed when mousenter the button again.
How do I prevent this happening?
Instead of using separate funcitons for the fadeIn and slide effect I decided to implement both in a single animate() function, then I just added some CSS resets to make sure the element is ready before starting the animation:
$(document).ready(function () {
var _duration = 1000;
$('#show-effect-1').hover(function () {
var $next = $('.text-banner');
$next.show();
$next.stop(true, true).css({
'margin-left': $next.outerWidth() * -1,
'margin-top': 0,
'opacity': 0,
'display': 'block'
}).animate({
'margin-left': 0,
'opacity': 1
}, _duration);
}, function () {
var $next = $('.text-banner');
$next.stop(true, true).animate({
'margin-top': $next.height() * -1,
'opacity': 0
}, _duration, function () {
$(this).hide();
});
});
});
Check the Updated fiddle
Note that I had to add a container to accurately reproduce the slide effect, you can test without it and see if it's something you actually need