jQuery scrolling DIV: stop scrolling when DIV reaches footer - javascript

I have a #sidebar (which starts below my #header div) and a #footer (around 120px off the bottom of the page).
I'm trying to make the sidebar scroll with the content of the page. The code below does this semi-successfully:
/* profile sidebar */
#sidebar>div{ width: 300px; margin-top: 10px; }
#sidebar.fixed>div{position:fixed;top:0;}
#sidebar.fixed_bottom>div{position:fixed;bottom:172px;}
jQuery(function ($) {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var el = $('#sidebar'),
pos = el.position().top;
$(window).scroll(function() {
if ($(this).scrollTop() >= pos) {
if ( $(this).scrollBottom() <= 172 ) {
el.removeClass('fixed');
el.addClass('fixed_bottom');
} else {
el.removeClass('fixed_bottom');
el.addClass('fixed');
}
} else {
el.removeClass('fixed');
}
});
});
The problem is, on smaller resolutions, this makes the sidebar "jump" once you reach a certain position on the page. It stops it from overlapping the footer (which is the problem if you remove the fixed_bottom class) but doesn't look good.
What I'd like to do is this: user scrolls to the bottom of the page, the sidebar scrolls along with the content until it reaches say 20px above the top of my footer, at which point it stays there until the user scrolls back up.
Thanks in advance,

I believe this should do what you want.
http://jsfiddle.net/FDv2J/3/
#sidebar>div{ width: 100px; margin-top: 10px; position:fixed; left: 0; top: 0;}
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#sidebar>div');
var $window = $(window);
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 172 - $window.scrollBottom();
var scrollTop = $window.scrollTop()
if(scrollTop < 172 + 10){
$el.css({
top: (172 - scrollTop) + "px",
bottom: "auto"
});
}else if (visibleFoot > gap) {
$el.css({
top: "auto",
bottom: visibleFoot + "px"
});
} else {
$el.css({
top: 0,
bottom: "auto"
});
}
});
});
I tried to break things up and name variables in such a way that it would be understandable. Let me know if there's anything you're unsure of. Notice that I added resize as well as scroll since it matters if the window changes size.
EDIT: Modified version using similar technique to the original to find the upper bound:
http://jsfiddle.net/FDv2J/4/
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#sidebar>div');
var $window = $(window);
var top = $el.parent().position().top;
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 172 - $window.scrollBottom();
var scrollTop = $window.scrollTop()
if (scrollTop < top + 10) {
$el.css({
top: (top - scrollTop) + "px",
bottom: "auto"
});
} else if (visibleFoot > gap) {
$el.css({
top: "auto",
bottom: visibleFoot + "px"
});
} else {
$el.css({
top: 0,
bottom: "auto"
});
}
}).scroll();
});
body{
margin: 0;
}
#sidebar>div {
width: 100px;
height: 300px;
margin-top: 10px;
background-color: blue;
position: fixed;
}
#stuff {
height: 1000px;
width: 300px;
background-image: url("http://placekitten.com/100/100")
}
#footer,
#header {
height: 172px;
width: 300px;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sidebar">
<div class="fixed">sidebar</div>
</div>
<div id="stuff">
</div>
<div id="footer">
</div>

Related

Header disappearing on scroll

I'm trying to make my header disappear when scrolling down and only re-appear when scrolling up. I can't get it to work:
http://jsfiddle.net/mxj562qt/
Any ideas where I'm going wrong?
HTML:
<div id="header" class="custom-header">
This is your menu.
</div>
<main>
This is your body.
</main>
<footer>
This is your footer.
</footer>
Javascript:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $("#header").outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$("#header").addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
It would appear that the CSS class doesn't get added but I'm not sure why. Am I referencing the Div in the wrong way?
So, I can see that the issue stems from this bit of code ...
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
In my tests, the doc height was always > than the st + window height.
I did this ...
// Scroll Up
console.log('doc height: ', $(document).height());
console.log('st+window height: ', st + $(window).height());
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
// results from scrolling up + down
// doc height: 2058
// st+window height: 313
// doc height: 2058
// st+window height: 280
// doc height: 2058
// st+window height 1614
// doc height: 2058
// st+window height: 1580
Changing the aforementioned JS to this seems to get you where you need to be.
$("#header").removeClass('nav-up');
Then your CSS needed some work ...
I noticed that your top element wasn't applying due to the CSS selector priority.
.nav-up {
top: -50px !important;
}
The result: scrolling down, the nav bar hides, scrolling up, the navbar shows.
I forked your code below;
http://jsfiddle.net/itsbjk/aw6qb2mr/16/
The problem here is with your CSS. You have specified position:fixed; in your code and that bit of CSS overrides all the JS you are writing. Fixed will force your header to be visible no matter what you are doing. Instead, you could try this in your CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: absolute;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
The absolute property should make it disappear on scrolling. And also, your referencing of the <div> tag isn't wrong!

Horizontal scroll at the middle of the page

I want to change the scroll direction at the middle of the page.
I tried to do it with "jInvertScroll", but this plugin increase left in css, like that:left: /* increase on scroll */ px ;
So if I want to change the scroll direction to the middle of the page, left will already have a value like:left: -1500px;
That's my problem.
Is there another way to do it?
HTML :
<div class="vertical"></div>
<div class="menu-change"></div>
<div class="horizontal">
<p>scroll</p>
</div>
CSS :
body {
overflow-x: hidden;
padding: 0;
margin: 0;
}
.scroll {
position: fixed;
bottom: 0;
left: 0;
}
.vertical {
width: 100vw;
height: 2500px;
background-image: url(https://source.unsplash.com/random);
}
.horizontal {
width: 8500px;
height: 100vh;
background-image: url(https://source.unsplash.com/random);
}
JS :
$(document).ready(function(){
var scroll_start = 0;
var startchange = $('.menu-change');
var offset = startchange.offset();
$(document).scroll(function() {
scroll_start = $(this).scrollTop();
if(scroll_start > offset.top) {
$('.horizontal').addClass('scroll');
var elem = $.jInvertScroll(['.scroll'],
{
onScroll: function(percent) {
console.log(percent);
}
});
$(window).resize(function() {
if ($(window).width() <= 0) {
elem.destroy();
}
else {
elem.reinitialize();
}
});
} else {
$('.horizontal').removeClass('scroll');
}
});
});

Changing the position of a fixed image with scrollposition

For my own portfolio I have an one-page website. To make it more personal i've created a low poly version of my head which is the fixed image.
But how do i change its position depending on which section is currently being viewed?
Example: When somebody is visiting the website and click on "About" the page would scroll down and the image would animate to the left so there will be more space for the content I want to display.
The CSS of the image:
img.imgPerson{
position: fixed;
z-index:2;
top: 48%;
left: 50%;
margin-top: -242px;
margin-left: -175px;
}
What I've tried with Javascript already:
$(window).scrollTop() > 450 {
$('.imgPerson').animate({
"left": '350px'
}, 300);
}
Working fiddle.
You should use if keyword and you've to wrap your code by scroll event :
var animate_right = true;
var animate_left = true;
$(window).on('scroll', function(){
if( $(window).scrollTop() > 450 ){
if(animate_right){
animate_right=false;
animate_left=true;
$('.imgPerson').animate({"left": '550px'}, 300);
}
}else{
if($('.imgPerson').css('left')=='550px'){
animate_left=false;
animate_right=true;
$('.imgPerson').animate({"left": '250px'}, 300);
}
}
})
Hope this helps.
var animate_right = true;
var animate_left = true;
$(window).on('scroll', function(){
if( $(window).scrollTop() > 450 ){
if(animate_right){
animate_right=false;
animate_left=true;
$('.imgPerson').animate({"left": '550px'}, 300);
}
}else{
if($('.imgPerson').css('left')=='550px'){
animate_left=false;
animate_right=true;
$('.imgPerson').animate({"left": '250px'}, 300);
}
}
})
body{
height: 1000px;
}
img.imgPerson{
position: fixed;
z-index:2;
top: 48%;
left: 50%;
margin-top: -242px;
margin-left: -175px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src='http://android-foundry.com/wp-content/uploads/signup2-img.png' class='imgPerson'/>

Keep selected div centered when zooming

I have this HTML code:
<div class="inner">
<div class="nhood">
<div class="image"></div>
</div>
</div>
And this CSS:
.image {
width: 4000px;
height: 4000px;
background: beige;
margin: 150px;
position: absolute;
}
.nhood {
overflow: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
background: black;
}
The .image div is filled with 400 divs, all floating left, creating a huge 'chess'-pattern, the code is the following:
.image > div {
border: 1px dotted;
width: 5%;
height: 5%;
float: left;
box-sizing:border-box;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
position: relative;
user-select: none;
}
You are able to click on any cell to show its info, and the whole .image div is draggable. Now if you have selected a cell and you ZOOM (which basically only shrinks/extends the 4000x4000 div to 2000x2000 or the other way round) it zooms in ANYWHERE but I want to keep focus on the cell that was selected earlier.
I have made an image of this:
http://smimoo.lima-city.de/zoom.png
I hope this was any clear...
EDIT:
JS
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 0
});
});
}
function zoomOut() {
$(draggable).animate({
height: '2000',
width: '2000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 1
});
});
EDIT2:
This is my js to center the function (written before Mario helped me out):
function centerField() {
var myObject = $(draggable).find('.selected');
var docWidth = ($(viewport).width() / 2) - (myObject.outerWidth()/2);
var docHeight = ($(viewport).height() / 2) - (myObject.outerWidth()/4);
var myOff = myObject.offset();
var distanceTop = myOff.top - docHeight;
var distanceLeft = myOff.left - docWidth;
var position = $(draggable).position();
var left = position.left;
var top = position.top;
var right = left - $(viewport).width() + draggable.outerWidth(true);
var bottom = top - $(viewport).height() + draggable.outerHeight(true);
if(left - distanceLeft > 0) {
distanceLeft = left;
}
if(right - distanceLeft < 0) {
distanceLeft = right;
}
if(top - distanceTop > 0) {
distanceTop = top;
}
if(bottom - distanceTop < 0) {
distanceTop = bottom;
}
$(draggable).animate({
left: '-=' + distanceLeft,
top: '-=' + distanceTop
}, { duration: 200, queue: false });
}
Assume that the selected div has the class .selected, this function will center the div:
function centerSelected() {
var selectedElement = $('.image .selected');
var p = selectedElement.position();
var w = $('.nhood').width();
var h = $('.nhood').height();
var offsetX = (w/2)-p.left - (selectedElement.width() / 2);
var offsetY = (h/2)-p.top - (selectedElement.height() / 2);
if(offsetX > 0) offsetX = 0;
if(offsetY > 0) offsetY = 0;
$('.image').css('left', offsetX + 'px');
$('.image').css('top', offsetY + 'px');
}
Just call centerSelected after every zoom operation.
Here is a jsfiddle with slightly modified css to get the presentation work:
http://jsfiddle.net/q1r95w3g/3/
Edit
If you want the div to get centered during jQuery animation, you can call centerSelected in the step callback of the animate method, e.g.:
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
},{
duration: 600,
complete: function() {
$divs.animate({
borderWidth: 0
});
},
step: function(now, fx) {
centerSelected();
}
});
}

Change a div width on window scroll

I'm trying to make a javascript effect on a div like a garage door.
Basically I'd have an absolute div on the back and another div on the front which would shrink from bottom to top base on window school.
I've found a similar jsfiddle, but it's doing it on the width instead on the height and I'd like the div top to stay fixed and shrink from bottom to top.
JSFiddle Code
HTML
<div id="added">
<div id="container">
My center div...
</div>
</div>
CSS
#added {
background: #eee;
height: 2000px;
overflow:hidden;
}
#container {
width: 800px;
height: 2000px;
background-color: #567;
margin: 0 auto;
position:relative;
}
JS
$(window).resize(function() {
$('#container').css({
top: ($(window).height() - $('#container').outerHeight()) / 2
});
});
// To initially run the function:
$(window).resize();
var $scrollingDiv = $("#container");
$(window).scroll(function() {
var winScrollTop = $(window).scrollTop() + 0,
zeroSizeHeight = $(document).height() - $(window).height(),
newSize = 800 * (1 - (winScrollTop / zeroSizeHeight));
$scrollingDiv.css({
width: newSize,
"marginTop": winScrollTop + "px"
}, 500, 'easeInOutSine');
});
Any help will be appreciated.
Thank You
You can try that :
var $scrollingDiv = $("#container"),
defaultHeight = parseInt($scrollingDiv.css('height')); // whatever is in your css as
$(window).scroll(function() {
var winScrollTop = $(window).scrollTop() + 0,
zeroSizeHeight = $(document).height() - $(window).height(),
newSize = defaultHeight * (1 - (winScrollTop / zeroSizeHeight));
$scrollingDiv.css({
height: newSize,
"marginTop": winScrollTop + "px"
}, 500, 'easeInOutSine');
});
Set Both to auto
CSS
#added {
background: #eee;
height: auto;
width: auto;
}
It automatically add scroll bar no need to apply java script

Categories

Resources