I've got a back to top button that shows up on my webpage that I'm working on. When you scroll down and sometimes when it's clicked it jumps to the top and then jumps back to where you were on the page and then smoothly scrolls to the top like it's supposed to. Keep in mind that it does not do this all the time. Would this just be a lag or glitch issue or if there some error in my script?
$(function(){
$(document).on( 'scroll', function(){
if ($(window).scrollTop() > 615) {
$('.ion-android-arrow-dropup-circle').addClass('show');
} else {
$('.ion-android-arrow-dropup-circle').removeClass('show');
}
});
$('.ion-android-arrow-dropup-circle').on('click', scrollToTop);
});
function scrollToTop() {
verticalOffset = typeof(verticalOffset) != 'undefined' ? verticalOffset : 0;
element = $('body');
offset = element.offset();
offsetTop = offset.top;
$('html, body').animate({scrollTop: offsetTop}, 500, 'linear');
};
Searched 40+ questions and couldn't find an answer. Only saying this because if you don't and somebody finds one they always say, "You should have looked before asking." I see it all the time.
ANSWER TO MY OWN QUESTION
After going so long without responses I had moved on and decided not to worry about this issue at that time. Today, I was working on a different site using the same jQuery script and was having the same problem. I decided to try and fix it myself since I couldn't find help on the issue.
The solution was simple! I don't know how I missed it the first time around. All I did is take the above code and add one function to it:
$('.ion-android-arrow-dropup-circle').click(function(event) {
event.preventDefault()
});
I forgot all about needing to remove the default action of clicking a link which is jumping to the destination. It now works perfectly smooth and looks great, just like I wanted to begin with!
My fully updated script for your reference:
$(function(){
$(document).on( 'scroll', function(){
if ($(window).scrollTop() > 50) {
$('.ion-eject').addClass('show');
} else {
$('.ion-eject').removeClass('show');
}
});
$('.ion-eject').click(function(event) {
event.preventDefault()
});
$('.ion-eject').on('click', scrollToTop);
});
function scrollToTop() {
verticalOffset = typeof(verticalOffset) != 'undefined' ? verticalOffset : 0;
element = $('body');
offset = element.offset();
offsetTop = offset.top;
$('html, body').animate({scrollTop: offsetTop}, 200, 'linear');
};
Related
I am trying to automatically .animate the .scrollTop of a <div> contained within another <div>. I have done this so I could hide the scroll-bar thus only display the text. Therefore, I know how to scroll that particular <div> with JQuery as such:
$("#div").animate({ scrollTop: "+=5" }, 200);
But what I am trying to do is to continuously .animate the content until it reaches the bottom of that particular <div> and then animates back to the top of the <div> ( .scrollTop: '0px'). THere is where I am struggling with.
I am currently pulling content into a <div> which the result of a
query. Therefore, I do not know the full length of the content that
will be placed of that <div>.
The <div> that contains the content is within another <div> and I don't think the method to detect the bottom of the <div> works correctly (or perhaps I am doing something wrong).
var div = $(this);
if (div[0].scrollHeight - div.scrollTop() == div.height())
I was wondering if someone can give me a hand with this. Since I have not seen a particular approach like this in this forum or by Googleing for it.
So pretty much what I have is this:
if ($('#resultProviders').scrollTop() >= $('#resultProviders').innerHeight()) {
$('#resultProviders').animate({ scrollTop: "0px" }, 800);
} else {
$('#resultProviders').animate({scrollTop: '+=30px'}, 500);
};
I have also provided a Fiddle for this.
https://jsfiddle.net/trinkermedia/ebhydbp3/5/
Many thanks.
I'd use a scroll function with a parameter, like shown in this fiddle.
function _scroll(goDown) {
goDown = goDown == undefined ? true: goDown;
var frame = $('#resultProviders'),
content = $('#resultProviders ul'),
scrollTo;
if (goDown) {
scrollTo = content.outerHeight() - frame.outerHeight();
} else {
scrollTo = 0
}
frame.animate({
scrollTop: scrollTo
}, {
duration: 2000,
complete: function() {_scroll(!goDown)}
});
}
Things are so simple with GSAP, here is your fiddle: jsFiddle.
JavaScript:
TweenMax.to('#resultProviders', 2, { scrollTo: { y: 'max' }, repeat: -1, yoyo: true, ease: Power2.easeInOut });
Apologies if this wasn't you were looking for or if you were not interested in solutions utilising anything else other than jQuery.
I am building a full page slider that keeps the native scrollbar and allows the user to either free scroll, use the mouse wheel or navigation dots (on the left) to switch to a slide.
Once the user is on the last slide and tries to scroll down further, the whole slider moves up to reveal a simple scrollable section. If the user scrolls down and then tries to go back up, then this new section moves out of the way again and returns the slider back into view.
Fiddle: http://jsfiddle.net/3odc8zmx/
The parts I'm struggling with:
Only the first two navigation dots work. The third one DOES WORK if you area looking at the first slide. But doesn't do anything, if you are on slide 2. Note: the purple one is a short-cut to the second section of the page and not related to the slider.
When moving to the last slide (via the dots, if you're on the first slide) it causes the code to make the whole slider move upwards as it sees this as the user has slid past the last slide as per the description above. I have tried to combat this using a variable called listen to stop the scroll event listening when using the showSlide method... but it seems to be true even though I set it to false, and only reset it to true again after the animation...
When scrolling down using the mouse wheel, I can get to the second section and back up, but not to the first third section. I'm wondering if I could use the showSlide method to better handle this instead of the current dirty next and prev functions I have implemented.
Note: If the user has free-scrolled, when they use the mouse-wheel, I want the slider to snap to the nearest slide to correct itself... Any suggestions for how I could do this?
Can anyone offer some help?
Here's the JS:
var listen = true;
function nextSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: $('#section1').scrollTop() + $(window).height()
});
}
function prevSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: -$('#section1').scrollTop() + $(window).height()
});
}
function showSlide(index)
{
var offset = $('#section1 div').eq(index).offset();
offset = offset.top;
if(offset){
listen = false;
$('.slide-dot').removeClass('active');
$('.slide-dot').eq(index).addClass('active');
$('#section1').stop(true,false).animate({
scrollTop: offset
}, 500, function(){
listen = true;
});
} else {
alert('error');
}
}
$(document).ready(function(){
var fullHeight = 0;
$('#section1 div').each(function(){
fullHeight = fullHeight + $(this).height();
});
var lastScrollTop1 = 0;
$('#section1').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
if( $('#section1').scrollTop() + $(window).height() == fullHeight) {
if(listen){
$('body').addClass('shifted');
}
}
}
lastScrollTop1 = st;
});
$('#section1').on('mousewheel', function(e){
e.preventDefault();
var st = $(this).scrollTop();
if (st > lastScrollTop1){
nextSlide();
} else {
prevSlide();
}
});
var lastScrollTop2 = 0;
$('#section2').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
} else {
if( st == 0 ){
$('body').removeClass('shifted');
}
}
lastScrollTop1 = st;
});
$('.slide-dots').css({'margin-top':-$('.slide-dots').height() / 2});
$('.slide-dot').first().addClass('active');
$(document).on('click', '.slide-dot', function(e){
e.preventDefault();
showSlide( $(this).index() );
});
$(document).on('click', '.slide-dot-fake', function(e){
e.preventDefault();
$('body').addClass('shifted');
});
});
And for those wondering why I'm not using something like fullPage.js, it's because it can't handle the way I want to transition between the two areas and have two scrollbars (one for each area).
You can use:
e.originalEvent.wheelDelta
instead of:
st > lastScrollTop1
in the mousewheel event for your third problem to check if the user has scrolled up or down. And also change the +/- in prevSlide. I used dm4web's fiddle for your first problem. And I used:
scrollTop: offset - 1
instead of:
scrollTop: offset
for your second problem, because when the scroll reaches to the last pixel of the third element, it automatically goes to the next section, so 1 pixel is enough for it not to.
Here's the fiddle: http://jsfiddle.net/3odc8zmx/3/
As suggested by #chdltest, you could do it by using fullPage.js.
Here's an example. Go to the last section.
Code used for the example:
Javascript
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
scrollOverflow: true,
scrollBar: true,
afterLoad: function (anchor, index) {
//hiding the main scroll bar
if (index == 4) {
$('body, html').css('overflow', 'hidden');
}
//showing the main scroll bar
if (index == 3) {
$('body, html').css('overflow', 'visible');
}
}
});
CSS (in case you prefer to use the normal style for it)
/* Normal style scroll bar
* --------------------------------------- */
.slimScrollBar {
display: none !important;
}
.fp-scrollable {
overflow: auto !important;
}
Advantages of using fullPage.js instead to your own code:
Strongly tested in different devices and browsers. (IE, Opera, Safari, Chrome, Firefox..)
Prevent problems with trackpads, Apple laptops trackpads or Apple Magic Mouse.
Old browser's compatibility, such as IE 8, Opera 12...
Touch devices compatibility (IE Windows Phone, Android, Apple iOS, touch desktops...)
It provides many other useful options and callbacks.
I'm having troubles getting this code to execute in a timely manner in Firefox. It seems to work just fine in Chrome.
JSFiddle here: http://jsfiddle.net/EXDhb/
Real live example page I'm working with here: http://mindevo.com/tests/tacos.html
I'm not sure if I'm leaving something out. I kind of hacked this together from reading a bunch of page-scroll scripts other people have put together. Not sure if this is even the best way for me to do what I'm trying to accomplish (which is to darken the next area until it's somewhat revealed. (I used halfway for this).
Here's my javascript:
$(document).ready(function(){
$(window).scroll(function(){
$('.dark').each(function(i){
var half_object = $(this).position().top + ($(this).outerHeight()/2);
var bottom_window = $(window).scrollTop() + $(window).height();
var bottom_object = $(this).position().top + $(this).outerHeight();
if(bottom_window > half_object){
$(this).animate({'opacity':'1'},200);
}
else if(bottom_object > $(window).scrollTop()) {
$(this).animate({'opacity':'.5'},200);
}
});
});
});
Is there a better way to do this? I tried adding/removing css classes but it invoked some crazy Chrome bug I was not pleased about.
Why does it work so slowly in Firefox?
Start by not having 6 separate jQuery $(this) operations and multiple $(window)! Use temp variables whenever you can to avoid requerying.
JSFIddle: http://jsfiddle.net/TrueBlueAussie/EXDhb/9/
$(document).ready(function () {
// window never changes
var $window = $(window);
$window.scroll(function () {
// Window height may have changed between scrolls
var windowHeight = $window.height();
var scrollTop = $window.scrollTop();
$('.dark').each(function (i) {
var $this = $(this);
var top = $this.position().top;
var outerH = $this.outerHeight();
var half_object = top + (outerH / 2);
var bottom_window = scrollTop + windowHeight;
var bottom_object = top + outerH;
console.log(half_object);
if (bottom_window > half_object) {
$this.stop().animate({
'opacity': '1'
}, 200);
} else if (bottom_object > scrollTop) {
$this.stop().animate({
'opacity': '.5'
}, 200);
}
});
});
});
And so on until you do not do anything twice that has an overhead that you do not need to have.
Update: Stop previous animations
The pause was not caused by the speed of the code above, but by not stopping multiple animations. The problem is that scroll fires frequently, so without .stop() animations get queued up and fire one after the other. This made it look much slower that it actually was.
Further optimizations might involve only processing elements that are actually onscreen, but that is pretty pointless given the apparent speed now.
You can cache your variables, which should help slightly:
$(document).ready(function(){
var $window = $(window);
$window.scroll( function(){
$('.dark').each(function(i){
var $this = $(this);
var outerHeight = $this.outerHeight();
var positionTop = $this.position().top;
var half_object = positionTop + (outerHeight/2);
var bottom_window = window.scrollTop() + window.height();
var bottom_object = positionTop + outerHeight;
if(bottom_window > half_object){
$this.animate({'opacity':'1'}, 200);
} else if(bottom_object > window.scrollTop()) {
$this.animate({'opacity':'.5'}, 200);
}
});
});
});
I realize there is already an accepted answer, but many times it is useful to do something only after the user has stopped scrolling, and not each time the "scroll" event fires. This event can can fire upwards of 50 times per second, leaving you with ~20ms to do what you need to do. This other StackOverflow question shows you how to do something only after scrolling has stopped. As #TrueBlueAussie mentioned in his answer, you would still want to stop any animations that were currently running.
Good evening everybody! Currently, on the site I'm working on (http://bit.ly/1eGCShX), I've got it to scroll down to each div all the way down, however after you've finished and click on the last one again, it doesn't scroll back all the way to the top (instead the previous div) and that's what I'm trying to accomplish.
However, I need it to repeat itself over again to start back from the first div, because if you finish it once and scroll up to click the first one again it stars where it left off. I've been messing with this for awhile and couldn't get it. Any help is kindly appreciated! Here is my JS;
$('div.section').first();
$('a.display').on('click', function(e) {
e.preventDefault();
var t = $(this).text(),
that = $(this);
if ($('.currentPanel').next('div.section').length > 0) {
var $next = $('.currentPanel').next('.section');
var top = $next.offset().top;
$('.currentPanel').removeClass('currentPanel');
$(function () {
$next.addClass('currentPanel');
$('html, body').animate({scrollTop: $('.currentPanel').offset().top }, 'slow');
});
} else if ($('.currentPanel').prev('div.section').length > 0) {
var $prev = $('.currentPanel').prev('.section');
var top = $prev.offset().top;
$('.currentPanel').removeClass('currentPanel');
$(function () {
$prev.addClass('currentPanel');
$('html, body').animate({scrollTop: $('.currentPanel').offset().top }, 'slow');
});of
}
});
And of course, the JSFiddle to make things x10 more easier! I've made a simplified version.
http://jsfiddle.net/dylanopet/ADsKH/9/
Again, appreciate for taking your time to read this and wish you all a positive week.
Where you have
var $prev = $('.currentPanel').prev('.section');
change it to
var $prev = $('.section').eq(0);
You were telling the function you wanted to scroll to the previous element. But you actually want to scroll to the first element.
Working example: http://jsfiddle.net/58ZMZ/
I have a "back to top" button that appears when the user scrolls down the page.
With some help I have managed to implement these functions in the code below:
fade in at certain point after scrolling down, animated scroll back to top and animated scrolling to all href="#" links of the page.
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 800, 'swing', function () {
window.location.hash = target;
});
});
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() > 300) {
b.fadeIn();
console.log("fadding in")
}
else {
b.fadeOut();
}
});
});
Here is a working exsample: http://jsfiddle.net/q8DUC/8/
My problem is that the button scrolls into the footer of the page...
Basically the "back to top" should stop 30px above the "footer" DIV.
But I can't find a way to accomplish that. I've looked around but haven't found anything that worked with the existing code.
Thanks for any help or suggestions!
UPDATE:
Got a bit further: http://jsfiddle.net/q8DUC/20/
Just don't know how I can avoid the jumping of the button!
Is there a way to stick the button to the bottom instead the top:0???
As always THANKS for every suggestion or help!
I think you could get the location of the footer and add it to your conditional, which checks if the button should be displayed:
// dynamically get the position of the footer
var FOOTER_POSITION = someNumber;
// i THINK something like var FOOTER_POSITION = $('#T4').position().top; could work
if (300 < $win.scrollTop() && $win.scrollTop() < FOOTER_POSITION) {
Sorry, I read your question wrong, since you are using fixed positioning for your button you could implement something like:
get the height of the footer + 30px
Get a location of the footer in relation to the document, based on your fiddle ~2000px (FOOTER_START)
if the location of the top of the window is > 300 AND it is greater than (FOOTER_START) change #back-top bottom property to height of your footer