In ready function scrollDown animation begin, in complete call back listener of scrollDown I called scrollUp function to commence the scroll up animation. After a cycle complete the scroll down animation take some time to start over again. More importantly the delay time increases after every cycle complete.
$(document).ready(function(){
scrollDown();
});
function scrollDown(){
$('html, body').animate({
scrollTop:$("#4").offset().top-100
},
{
duration:2000,
complete: function(){
scrollUp();
}
});
}
function scrollUp(){
$('html, body').animate({
scrollTop:$("#1").offset().top-100
},
{
duration:2000,
complete: function(){
scrollDown();
}
});
}
Adding $('html, body').stop(); did the trick, now animation is quit smooth and no delay time. But why I have to call he stop() function? Because I already implemented the complete call back.
$(document).ready(function(){
scrollDown();
});
function scrollDown(){
$('html, body').stop(); // no idea why I need to call this stop function
$('html, body').animate({
scrollTop:$("#4").offset().top-100
},
{
duration:2000,
complete: function(){
scrollUp();
}
});
}
function scrollUp(){
$('html, body').stop(); // no idea why I need to call this stop function
$('html, body').animate({
scrollTop:$("#1").offset().top-100
},
{
duration:2000,
complete: function(){
scrollDown();
}
});
}
Related
Using this javascript to scroll to a div (#Content) after a 5s delay using setTimeout.
setTimeout(function () {
$('html, body').animate({ scrollTop: $('#Content').offset().top - 0 }, 1000);
}, 5000);
How would I go about cancelling this action if the user scrolls manually before the 5s is elapsed. Reason being if the user has scrolled they'll be annoyed if the page then auto scrolls.
Tried putting it in window.load and checking for if ($(window).scrollTop() == 0) but of course that's always true at window.load, and isn't cancelled by the user scrolling manually.
Thanks!
you can use for example global variable and check if its set up by event scroll
var scrolled = false;
$(document).scroll(function(){scrolled = true;});
setTimeout(function () {
if (!scrolled){
$('html, body').animate({ scrollTop: $('#Content').offset().top - 0 },
1000); }
}
}, 5000);
You shall define your timeout into a variable to be able to cancel it with clearTimeout
See full documentation here : https://www.w3schools.com/jsref/met_win_cleartimeout.asp
Just add an event to check oyur scroll and cleart your timeout if scrolled
For example :
var myVar = setTimeout(function(){
$('html, body').animate({ scrollTop: $('#Content').offset().top - 0 }, 1000);
}, 5000);
and to cancel your scroll :
$(document).scroll(function(){
clearTimeout(myVar)
}
You can clear the timeout as others have shown, or you can let it run but perform the scrollTop check inside before starting the scroll animation:
setTimeout(function () {
if ($(window).scrollTop() == 0) {
$('html, body').animate({ scrollTop: $('#Content').offset().top - 0 }, 1000);
}
}, 5000);
You can run the logic for checking the scroll by adding an event hanlder for scroll and then removing the event handler once it is done checking as it needs to be run only once. Also, You can clear the setTimeout by using the clearTimeout in the eventHandler Code.
window.addEventListener('scroll', scrollEventHandler);
function scrollEventHandler(e){
clearTimeout(...setTimeoutid) // Pass in setTimeout Id.
}
setTimeout(function () {
$('html, body').animate({ scrollTop: $('#Content').offset().top - 0 }, 1000);
window.removeEventListener('scroll', scrollEventHandler);
}, 5000);
I have used window.location.hash to jump from a link on a page to a div on another page. This works well. However, when the new page opens, it shows first the top of the page and scrolls then down to the div. The code I used for this is given below.
Question: how can I change the code so that the new page is loaded at the div immediately, without scrolling (or jumping) from the top of the page to the div?
if (window.location.hash) {
setTimeout(function() {
$('html, body').scrollTop(0).show();
$('html, body').animate({
scrollTop: $(window.location.hash).offset().top
}, 1000)
}, 0);
}
else {
$('html, body').show();
}
I do it in this way because their is a timeout on the page during loading. When I do it in the normal way, thus without this code, it doesn't work because of the timeout. Any suggestions?
<script type="text/javascript">
var myVar;
function loadpage() {
myVar = setTimeout(showPage, 500);
}
function showPage() {
document.getElementById("loader").style.display = "none";
document.getElementById("myDiv").style.display = "block";
google.maps.event.trigger(map, 'resize')
map.setCenter(new google.maps.LatLng(50.849348, 4.7356652))
if (window.location.hash) {
setTimeout(function() {
$('html, body').scrollTop(0).show();
$('html, body').animate({
scrollTop: $(window.location.hash).offset().top
}, 0)
}, 0);
}
else {
$('html, body').show();
}
}
</script>
When You click on button, page should scroll down, to div with id="myTarget".
here is my HTML:
<button class="go"> GO </button>
<div id="myTarget">
<p>
la lalal lalala lalala
</p>
</div>
and jquery:
$(function() {
$(".go").on('click', function(event) {
event.stopPropagation();
$('html, body').animate({
scrollTop: $("#myTarget").offset().top }, 3000);
});
});
My problem is that when you click a few times on button, page scroll down. After that you can't scroll up. Is any way to stop click event while page moving?
JsFiddle
And if you stop the animation when user mousewheel?
$(function() {
$(".go").on('click', function(event) {
event.stopPropagation();
$('html, body').animate({
scrollTop: $("#myTarget").offset().top }, 3000);
});
});
var page = $("html, body");
page.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
page.stop();
});
Demo
What about disabling the button while it is running and enabling it again once animation is done?
$(function() {
$(".go").on('click', function(event) {
var $but = jQuery(this);
event.stopPropagation();
$but.attr("disabled", true);
$('html, body').animate({
scrollTop: $("#myTarget").offset().top }, 3000, "linear", function(){
$but.removeAttr("disabled");
});
});
});
I assume you mean that if you rapidly click the button a couple of times it'll scroll down and not let you scroll back up, and not that it doesn't work when you "Click Button, Scroll Down, wait, Scroll Up".
If it's the first case, you can fix it like this.
$(function() { $(".go").on('click', function(event) {
event.stopPropagation();
$(".go").attr("disabled", true).delay(3000).attr("disabled", false); $('html, body').animate({
scrollTop: $("#myTarget").offset().top
},
3000);
});
});
This means that when you click on the button, it will be disabled for 3000 milliseconds (the time of your animation. This should stop a user from being able to click on it and trigger the animation more than once while it's animating.
The issue is that your animation is getting appended onto the previous animation for the html and body tags. Thus, you have to wait for all of the animations that have been started to die before you can scroll back up.
Things that you can do about this problem
Make the duration of the animation smaller
Call stop() on the elements you are animating before creating the new animation
Call stop() if the window is scrolled. This solution could be problematic if you ever have the body tag doing other animations. The first two solutions should be enough, anyway.
The first should be self explanatory and the second is very easy:
$(".go").on('click', function(event) {
event.stopPropagation();
$('body').stop().animate({
scrollTop: $("#myTarget").offset().top }, 500);
});
You also only need to animate the body element (not the html element).
JSFiddle Example
Use a scrolling state, like so :
$(function() {
//global var
isScrolling = false;
$(".go").on('click', function(event) {
event.stopPropagation();
if(!isScrolling) {
isScrolling = true;
$('html, body').animate({
scrollTop: $("#myTarget").offset().top }, 3000,
//Only when it's completed (callback)
function() {
isScrolling = false;
}
);
}
});
});
Your problem is that it keeps trying to scroll down even though you are already down.
i have expandable headings that when clicked, show content.
I use a scrollTo method to scroll to the current clicked div to make sure its always in the screen view without the user scrolling.
However, where i currently use fadeIn / Out it looks messy as items are being faded in / out at the same time the page scrolling.
Is there a way i can only fade in / out the content when the scrollTo Has finished? e.g.:
Currently:
$(document).on('click','.headingHelp',function(){
$('html,body').animate({ scrollTop: $(this).offset().top }, 'slow');
$('.infoHelp').fadeOut();
$('.headingHelp_sel').attr('class', 'headingHelp');
$(this).next('.infoHelp').fadeIn();
$(this).attr('class', 'headingHelp_sel');
});
However what i want:
function scrollToDiv() {
$('html,body').animate({ scrollTop: $(this).offset().top }, 'slow');
}
$(document).on('click','.headingHelp',function(){
scrollToDiv() {
// ONLY DO THIS ONCE FINISHED SCROLLING
$('.infoHelp').fadeOut();
$('.headingHelp_sel').attr('class', 'headingHelp');
$(this).next('.infoHelp').fadeIn();
$(this).attr('class', 'headingHelp_sel');
}
});
You can use a callback:
$('html,body').animate({scrollTop: $(this).offset().top},'slow',function(){
//all the code you want to execute later goes here
});
If I recall correctly, you can make use of animate's promise:
function scrollToDiv() {
return $('html,body')
.animate({ scrollTop: $(this).offset().top }, 'slow').promise();
}
Use it like this:
scrollToDiv().done(function(){
$('.infoHelp').fadeOut();
$('.headingHelp_sel').attr('class', 'headingHelp');
$(this).next('.infoHelp').fadeIn();
$(this).attr('class', 'headingHelp_sel');
});
I've the following function:
$('.link1').click(function(){
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
});
It toggles a div and scroll the page down. The problem is that everytime the user toggles the page scroll down again...how could I run this animate function only at first click?
Use a flag or set a data attribute to make sure the scrolling animation only occurs on the first click.
var flag=true;
$('.link1').click(function(){
$("#div2").slideUp(function(){$("#div1").slideToggle();});
if (flag) {
$('html, body').animate({scrollTop: '600px'}, 800);
flag = false;
}
});
I'm guessing #div2 should still toggle, but that it just should'nt scroll on every click?
jQuery .one() http://api.jquery.com/one/
$('.link1').one( 'click', function(){
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
});
use the .one function to bind an event that fires only once.
$('.link1').one('click', function(){
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
});
The following works with JQuery.
The CSS used:
.cpos {
position: relative;
top: -1.65em;
left: 1.8em;
}
The JQuery used:
var p=null; /* Initialize variable p. */
p=$("b").detach(); /* Detach every possible <b>b</b>-tags. */
var p=$("<b>Console loaded!</b>").addClass("cpos"); /* Do anything, like adding class. */
p.appendTo("#container"); /* Append new data to the anchor container. */
Maybe you could use this for reference when animating. ;)
You could unbind that click handler at the end of the handler so that it never triggers again:
$('.link1').off('click');
Use a flag
var noRun = 0
$('.link1').click(function(){
if(noRun==1) {
return
}
noRun = 1
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
});
You can save a simple "token" to check if is the first time that click is fired in this way:
$('.link1').click(function(){
if(!$(this).data('isFirstTime')) {
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
$(this).data('isFirstTime', true);
}
});
This should prevent further click
This should do it
(function(){
var first=true;
$('.link1').click(function(){
if (first){
first=false;
$("#div2").slideUp(function(){$("#div1").slideToggle();});
$('html, body').animate({scrollTop: '600px'}, 800);
}
});
})();