ScrollTop goes to the wrong top - javascript

I have a list of items. When I click on one item (project) it opens (this is ok) and it scrolls to the top of the page (the wrong top!). The problem occurs when I have an opened item and I decide to open the one below: the top position is increased by the opened project height and the second project I click goes too far over the top.
Following the FIDDLE below: if I open project1 and then I click on project2, this goes on the wrong top. Same if I try to open any project below another opened one.
JS
$('.accordion-section-title').on('click', function () {
var idName = $(this).attr('id');
$('html, body').animate({
scrollTop: $("#" + idName).offset().top
}, 500);
});
Here's the FIDDLE

The problem seems to be the .slideUp() and .slideDown() methods are animated at the same time the window is scrolling. By the time the window has scrolled to the right Y coordinate, the accordion sections' heights have been altered, thus causing the window to end up in the wrong position.
I'm sure there are other ways to accomplish correct scroll positions, but my first thought was to store the initial Y positions once the page is loaded. This can be done this way:
$('.accordion-section-title').each(function() {
$(this).data('ypos', $(this).offset().top)
})
Each .accordion-section-title element will have its Y position stored in a data attribute called ypos. Later when you scroll the window, don't scroll to the elements position, but rather to its stored initial position. In other words, change scrollTop: $("#" + idName).offset().top to scrollTop: $("#" + idName).data('ypos'). Put together with your code it will look like the following:
$('.accordion-section-title').on('click', function(e) {
var idName = $(this).attr('id');
$('html, body').animate({
scrollTop: $("#" + idName).data('ypos') - 10
}, 500);
});
You can see how it plays out in this fiddle

Related

JQuery scroll window to show div depending on its location

When I click my button, I append a new div. I would like that, if any part of the div is not visible to the window, scroll untill it shows.
So if it is upwards from the center of the window, scroll up JUST until you see it's top, and if it is downwards from the center, scroll down just until you see its bottom.
In my searchings I found https://api.jquery.com/scrollTop/ , but that doesn't seem to be what I'm describing
I only want to scroll enough to display it entirely on screen, not always on top
Check this working fiddle for the solution.
You can use scrollTop() to scroll to any div. First we need to find the direction of the scroll to correctly provide the value for scrollTop() function. This can be found using position().
$('#button4').click(function() {
// check if the div lies below the button
if ($('#div3').position().top - $('#button4').position().top > 0) {
// in this case we need to add shift
var shift = $(window).height() - $('#div3').height();
} else {
var shift = 0;
}
$(window).scrollTop($('#div3').offset().top - shift);
});
Alternatively if you wish to check the position of the div relative to the current viewport (or the center of the current window view) you can use getBoundingClientRect() like:
$('#button4').click(function() {
// check if the div lies below the viewport
if ($('#div3')[0].getBoundingClientRect().top > 0) {
// in this case we need to add shift
var shift = $(window).height() - $('#div3').height();
} else {
var shift = 0;
}
$(window).scrollTop($('#div3').offset().top - shift);
});
Here is the alternate fiddle.
So if you are using jQuery.
//scroll top of element
var $myNewElement = $(".new-element-class");
$('html, body').scrollTop($myNewElement.offset().top)
I think this should work. Make sure your div is appended before calling the scrollTop function.
If I understand correctly, this jsfiddle is what you are looking for.
I also added a simple animation so the document doesn't awkwardly jump around the viewport.
Features
If a new element is created, and part of that new element is below the current viewport, the document will be scrolled until the bottom of the viewport is shown. Vice versa if part of the new element is above the current viewport.
If the new element is completely visible within the current viewport, no scrolling will occur.
All scrolling effects are animated.
A configurable offset (Leave some padding instead of scrolling to the very edge of the new element)
How it works
When the button is clicked, a new div element is appended.
$('section').append('<div>');
Next, we figure out if this div is above the current viewport using the below function:
function isElementAboveViewport(element) {
return $(element).offset().top < $(window).scrollTop();
}
in an if statement:
if (isElementAboveViewport($('section > div:last-child'))) {
...
}
If the condition is truthy, we scroll! (offset is configurable - In the JS fiddle, I used 40 which is the height of the button covering the top 40px of the viewport)
$('html, body').animate({
scrollTop: $('section > div:last-child').offset().top - offset
}, 1000);
Now, we check if the new element is below the current viewport with a similar function:
function isElementBelowViewport(element) {
return $(element).offset().top + $(element).height() > $(window).scrollTop() + $(window).height();
}
If the element is too far down in the document, we scroll! (Again, offset is configurable)
$('html, body').animate({
scrollTop: $('section > div:last-child').offset().top + $('section > div:last-child').height() - $(window).height() + offset
}, 1000);
Please let me know if this is what you were looking for and/or if you have any questions about how it works.

Jquery scroll until element reaches top

I have arrows in the center of my web pages at the end of sections and I was these to allow users to scroll to the next section on click. I have the following code where the first click works but subsequent clicks do not scroll even though the function is being called each time.
$('.scroll').on('click', function(event) {
alert('scroll');
$('html, body').animate({
scrollTop: $(".scroll").offset().top
}, 1000);
});
Can anyone assist? https://jsfiddle.net/avL459sm/2/
You should use current .scroll element you clicked on.
Look at this fiddle: https://jsfiddle.net/avL459sm/3/

Move html & body up to top when img is clicked

I have images that when clicked, resize. However, I would like it so that no matter how far the user scrolls, when an image is pressed the html and body will move to the top. I added an animation to the resize script but it seems to not be recognized.
$(".images img").on('click', function () {
$(this).toggleClass('selected');
$('html,body').animate({
scrollTop: $('.active').offset()
});
});
Code: http://jsfiddle.net/qSDP5/
EDIT*
I put a sticky header to the top of the page and used
$('html,body').animate({
scrollTop: $('#sticky').offset().top
});
But it doesn't seem to want to scroll to it.
It's because not only you don't have any element with the class of active, but also you are not defining the coordinate direction of that element you want to access, because of that your script doesn't scroll to that.
change this line :
scrollTop: $('.active').offset()
to this if you want to scroll to the top of the page
scrollTop: 0
or you can scroll to an element which resides in your html something like:
scrollTop: $('#header').offset().top
see this: http://jsfiddle.net/qSDP5/1/

JQuery .scrollTop() and .offset().top issue: how it work? How to solve?

I want to achieve some kind of smooth scrolling, so I made this script:
$('a').click(function(){
var sclink = $(this).attr('href');
$('.menu').animate({
scrollTop: $(sclink).offset().top
}, 500);
return false;
});
The problem? When I click on the 'a' the offset.top() value changes in another weird value and toggle between them? Why does this happen and how do I resolve it?
http://jsfiddle.net/StartStep/9SDLw/2947/
I think the problem is with the scroll.top() that gets the value in another way...
jsfiddle.net/9SDLw/2950/
$('a').click(function(){
var sclink = $(this).attr('href');
$('.menu').animate({
scrollTop: $(sclink).position().top
}, 500);
logit('Anchor: '+sclink+'; Offset top value: <b>'+$(sclink).offset().top+'</b>')
return false;
});
Use position instead of offset.
The reason is offset is relative to the viewport, as such it looks like you've scrolled too far, but this is because the top of your viewport area is being obscured by your layout, so offset is actually not what you want, instead, position is.
You should also add a reference to stop before calling animate to ensure if a user clicks in quick succession the behaviour is as expected (the animation queue is essentially flushed)
With that in mind your HTML also needs some work- the clickable link hasnt got closing tags for example.
Change your scrolling code to:
$('.menu').stop(true,true).animate({
scrollTop: $(sclink).position().top
}, 500);
Demo Fiddle

Can you get (using jQuery if possible) the current scrolled position of an element?

I am using this code on a 'down' button to scroll text in an overflowed div.
var textHeight = text.outerHeight();
var pageDown = $('#page-down');
var pageUp = $('#page-up');
pageDown.bind('click', function () {
pageUp.fadeIn(500);
text.animate({ scrollTop: '+=' + textHeight + 'px' }, 500);
});
This is working nicely, but I need a method to determine when the scroll down button should disappear ... i.e. when the last content has appeared inside the div.
Is there a property or method to get the scrolled position within that div? Thanks
Here's a couple links you may want to look at:
http://yelotofu.com/2008/10/jquery-how-to-tell-if-youre-scroll-to-bottom/
http://www.mail-archive.com/jquery-en#googlegroups.com/msg22400.html
I feel stupid... this returns a number I can use:
console.log($('#text').attr('scrollTop'));

Categories