Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery scroll to bottom of ID element

I'm trying to have a button that scrolls the page to a given element id. I currently have this Fiddle, but I would like it somewhat different:

  1. Scroll until the bottom of the blue div (#three) is at the bottom of the page, instead of top of div scrolling to top of page.
  2. Only scroll if the element is not visible on the screen to the user.

How can this be done?

HTML

<button id="btn">CLICK</button>
<div class="test" id="one"></div>
<div class="test" id="two"></div>
<div class="test" id="three"></div>
<div class="test" id="four"></div>

CSS

.test {
    width: 100%;
    height: 400px;
}

#one { background: red; }

#two { background: green; }

#three { background: blue; }

#four { background: yellow; }

JS

$("#btn").click(function() {
    $('html, body').animate({
        scrollTop: $("#three").offset().top
    }, 500);
});
like image 275
Chris Avatar asked Mar 15 '23 16:03

Chris


2 Answers

Okay here is the first part -

$('html, body').animate({
    scrollTop: ($("#three").offset().top + $("#three").height() - $(window).height())
}, 500);

just a little bit of Maths and you can easily understand by yourself what's going on.

and for the second part -

if(($('#three').offset().top >= $(window).scrollTop()) && ($('#three').offset().top < $(window).scrollTop() + $(window).height())) { ...
}

A complex comparison of values, to check visibility if top offset of element is in between window scrollTop() and + window height() (i.e something like offset bottom of window).

Check out the fiddle

UPDATE: there was a bug in the previous one, you need an additional conditional statement to check visibility of the #three by considering bottom offset of the element between window scrollTop() and bottom offset of window. So the full condition will become -

var eloffbottom = $('#three').offset().top + $('#three').height();
var winoffbottom = $(window).scrollTop() + $(window).height();
if((($('#three').offset().top >= $(window).scrollTop()) && ($('#three').offset().top < winoffbottom)) || ((eloffbottom >= $(window).scrollTop()) && (eloffbottom < winoffbottom))) {
                alert('already in view');
    }

UPDATED Fiddle fully working!

By the way, just found a plugin of jQuery which can do that for you. See here. Just use it as - $('#three').visible() - returns true or false.

like image 133
Rohit Kumar Avatar answered Mar 19 '23 17:03

Rohit Kumar


Calculate the top by subtracting the window height from the offset top of the element and then adding the element height.

Demo

$("#btn").click(function() {
  var winHeight = $(window).height(),
    topOffset = $("#three").offset().top,
    elementHeight = $('#three').height()
  var top = topOffset - winHeight + elementHeight;

  $('html, body').animate({
    scrollTop: top
  }, 500);
});
.test {
  width: 100%;
  height: 400px;
}
#one {
  background: red;
}
#two {
  background: green;
}
#three {
  background: blue;
  border: solid 3px gray;
}
#four {
  background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<button id="btn">CLICK</button>
<div class="test" id="one"></div>
<div class="test" id="two"></div>
<div class="test" id="three"></div>
<div class="test" id="four"></div>
like image 41
Tushar Avatar answered Mar 19 '23 16:03

Tushar