Find div closest to the bottom of the page - javascript

I am working on a project and I have an array of elements that are displayed one under each other.
When I press an arrow, I want to find the div closest to the bottom and scroll up to the top of that div.
This is what I have when I click the arrow:
$(".my-elements").each(function(i){
var divTopPosition = $(this).offset().top;
var scrollTop = $(window).scrollTop();
var difference = -Math.abs(scrollTop - divTopPosition);
if(/* this is the div closest to the bottom */)
{
$("body").animate({scrollTop: difference}, 2000);
return false;
}
});

if you know parent, you can use this selector:
$( "<parent>:last-child" )

Related

Calculate offset top of elements inside of a scrollable div

How can I calculate offset top inside a scrollable div? I have two divs that I want scroll inside my content div, and I want to set 2 variables to true/false, depending on where they are positioned inside that content div.
I tried something like this but I guess it calculates the entire page offset, it doesn't really work. I bind scroll to that content div, and I want to calculate their positon:
angular.element(slideContent).bind("scroll", function () {
var contentScrollTop = angular.element(slideContent).scrollTop();
var slideOneOffset = slideOne.offset().top;
var slideTwoOffset = slideTwo.offset().top;
var firstSlideDistance = (contentScrollTop - slideOneOffset);
var secondSlideDistance = (contentScrollTop - slideTwoOffset);
});
I think this should get you most of the way there:
// Position of first element relative to container top
var scrollTop = $(".container .element").offset().top - $(".container").offset().top;
// Position of selected element relative to container top
var targetTop = $(".container > *").offset().top - $(".container").offset().top;
// The offset of a scrollable container
var scrollOffset = scrollTop - targetTop;
// Scroll untill target element is at the top of its container
$(".container").scrollTop(scrollOffset);
———————————
EDIT (May 31 2018)
I guess this is better:
var scrollOffset = $(".container .element")[0].offsetTop - $(".container")[0].offsetTop

Add class depending on top-position value

I have tooltips set on top of an image. When the user clicks one of these tooltips a content opens to reveal some info.
I'd like to slide open the content up or down, depending where the tooltip is positioned (absolute). So, I'm trying to get the "top"-value and if it's larger than 50, add a class and sort out the rest with CSS.
The problem is I'm always just getting the "top"-value of the first element. Now I tried to add an each function, which leaves me with what seems to be the average value of all the tooltips' top positions?
$( ".tooltip" ).each(function() {
var toppos = $(".tooltip").css("top");
if ( parseInt(toppos) >= 50 ) {
$(this).addClass('higher');
}
});
I'm either using each wrong, or each is not what I should be going for here...
Target the current tooltip instead of all tooltips:
$( ".tooltip" ).each(function() {
var toppos = $(this).css("top");// Use $(this) instead of $('.tooltip')
if ( parseInt(toppos) >= 50 ) {
$(this).addClass('higher');
}
});
You may also try offset().top instead of css('top'):
var toppos = $(this).offset().top;

How to get the first entirely visible element within an element that has horizontal scrolling using jQuery?

I need to get the first element that is entirely visible within a scrollable DIV using jQuery. I'm close, but something isn't right.
Can anyone spot the problem?
$('div').on('scroll', function () {
var cutoff = $(this).scrollLeft();
$('li').removeClass('firstVisible').each(function () {
var $this = $(this);
if ($this.offset().left > cutoff) {
$this.addClass('firstVisible');
return false; // stops the iteration after the first one on the screen
}
});
console.log($('li.firstVisible').index());
});
JSFiddle
$this.offset() will return position relative to document (not to div with scrolling), so to check visibility you need to compare it to div position (not scroll left)
$('div').on('scroll', function () {
var cutoff = $(this).offset().left;
$('li').removeClass('firstVisible').each(function () {
var $this = $(this);
if ($this.offset().left >= cutoff) {
$this.addClass('firstVisible');
return false; // stops the iteration after the first one on the screen
}
});
here is an example: http://jsfiddle.net/axwR7/2/

Scroll Div With increase height

$(".clickable").each(function(idx, elem) { // register click for slides
elem = $(elem);
elem.click(function() {
scaleClicked(elem);
});
});
function scaleClicked(elem) { // slide clicked
var id = elem.attr("id"),
num = id.slice(-1),
postId = "post"+num,
posts = $(".post");
posts.each(function(idx, p) {
if($(p).attr("id") == postId) {
scaleUp(p);
}
else {
scaleDown(p);
}
});
}
function scaleUp(item) {
$(item).animate({height:1000},1000);
}
function scaleDown(item) {
$(item).animate({height:30},1000);
}
I need to Increase div height on click, like example 01 and at the same time, That Div Must scroll to Top of the window Like Example 02. Can You Help With This.
i tried few ways but when div increase the height, but it is scrolling to beyond the top level. but i need to stop div,when it scroll to top level of the window.
Instead of using an anchor to scroll like the example you gave you can scroll like this, for example to scroll to the bottom of a div:
$("#mydiv").animate({ scrollTop: $('#mydiv')[0].scrollHeight}, 1000);
To scroll to an item in the div you can find the position to scroll to in a number of ways, there's a good discussion here:
How do I scroll to an element within an overflowed Div?

Making nav bar effects using scroll AND click in jQuery

I want a nav to highlight (or something similar) once a user clicks on it AND when a user scrolls to the corresponding section.
However, on my computer when one clicks on any of the nav events after3, only nav event 3 changes. I'm guessing this is because after one clicks on 4 or 5, the scroll bar is already at the bottom of the page, so 4 and 5 never reach the top. The only div at the top is post 3, so my code highlights nav event 3 and ignores the click.
Is there any way I can fix this? Ive tried if statements (only highlight nav event if it's at the top AND the scrollbar isn't at the bottom or the top isn't the last item).
Here is a more accurate fiddle, using a fix below showing what I am talking about. The fix now highlights on scroll, but if you click option 5, it will not highlight.
$('.option').children('a').click(function() {
$('.option').css('background-color', '#CCCCCC;');
$(this).css('background-color', 'red');
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$(window).scrollTop(postLocation);
});
$(window).scroll(function() {
var scrollBar = $(this).scrollTop();
var allPosts = [];
var post = $('.content').offset();
var lastPost = allPosts.legnth-1
var windowHeight = $(window).height();
var bottomScroll = windowHeight-scrollBar;
$(".content").each(function(){
allPosts.push($(this).attr('id'));
});
i = 0;
for(i in allPosts){
var currentPost = "#"+allPosts[i];
var postPosition = $(currentPost).offset().top;
if (scrollBar >= postPosition){
$('.option').css('background-color', '#CCCCCC');
$('#nav'+allPosts[i]).css('background-color', 'red');
};
};
});
I think you've overdone your scroll() handler, to keep it simple you just needs to check if the scrollbar/scrollTop reaches the '.contents' offset top value but should not be greater than its offset().top plus its height().
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
$(".content").each(function (index) {
var elTop = $(this).offset().top;
var elHeight = $(this).height();
if (scrollBar >= elTop - 5 && scrollBar < elTop + elHeight) {
/* $(this) '.content' is the active on the vewport,
get its index to target the corresponding navigation '.option',
like this - $('.Nav li').eq(index)
*/
}
});
});
And you actually don't need to set $(window).scrollTop(postLocation); because of the default <a> tag anchoring on click, you can omit that one and it will work fine. However if you are looking to animate you need first to prevent this default behavior:
$('.option').children('a').click(function (e) {
e.preventDefault();
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$('html, body').animate({scrollTop:postLocation},'slow');
});
See the demo.
What you are trying to implement from scratch, although commendable, has already been done by the nice folks at Bootstrap. It is called a Scrollspy and all you need to do to implement it is include Bootstrap js and css (you also need jquery but you already have that) and make some minor changes to your html.
Scrollspy implementation steps.
And here is a demonstration. Notice only one line of js. :D
$('body').scrollspy({ target: '.navbar-example' });

Categories

Resources