Hi I got this code from another question and it works great. The only problem that I have is that there is padding-top added to the header I am using it on. I would like the padding to decrease along with the height to the point where there is no padding, I don't know how to add that attribute to this code. Can someone help? I would like them to decrease at the same rate so the content stays centered vertically.
the initial padding-top is set to this padding: 40px 0 0;
here is the jquery
var header = $('#main'),
headerH = header.height();
$(window).scroll(function() {
if ($(this).scrollTop() <= headerH / 2) {
header.css({
height: -($(this).scrollTop() - headerH)
});
} else {
header.css({
height: headerH / 2
});
}
}).scroll();
here is the question i got the initial jquery from: Shrink header height by scrollTop value
What about this one? DEMO http://jsfiddle.net/yeyene/xaDLy/1/
You can maintain css properties easily.
var header = $('#main'),
headerH = header.height();
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
header.stop().animate({
padding: '10px 0px 10px 0px'
}, 300);
} else {
header.stop().animate({
padding: '40px 0 40px 0'
}, 300);
}
});
Related
I have this problem which is probable very simple to solve, but I'm a newbie with JS/JQuery.
I have this code (see fiddle here: https://jsfiddle.net/Tiph/6ep3hp4j/) where my div footer shows when the scroll gets at the bottom of the document, but I want it to show when the scroll gets at a certain height under my header and have a fixed position at the bottom of my window. I understand that I have to calculate something with window.height, and/of offsetTop, but nothing works.
Someone can help me with it?
Thank you so much! :-)
my code here:
var footer = $('#footer'),
extra = 10;
footer.css({ opacity: '0', display: 'block' });
$(window).scroll(function() {
var scrolledLength = ( $(window).height() + extra ) + $(window).scrollTop(),
documentHeight = $(document).height();
console.log( 'Scroll length: ' + scrolledLength + ' Document height: ' + documentHeight )
if( scrolledLength >= documentHeight ) {
footer
.addClass('bottom')
.stop().animate({ bottom: '0', opacity: '1' }, 300);
}
else if ( scrolledLength <= documentHeight && footer.hasClass('bottom') ) {
footer
.removeClass('bottom')
.stop().animate({ bottom: '-100', opacity: '0' }, 300);
}
});
I create new sample code for you to understand how its work
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(window).scroll(function() {
var count=700;
var menuHeight = $('#footer').height()+count;
var top = $(this).scrollTop();
var bottom = $(document).height() - $(this).height() - $(this).scrollTop();
if (bottom < menuHeight) {
$('#footer').removeClass( 'top' );
$('#footer').addClass( 'bottom' );
$('#footer').fadeIn( 'slow' );
}
else {
$('#footer').fadeOut( 'slow' );
}
});
});
</script>
<meta charset="utf-8">
</head>
<body>
<style>
#footer{
width: 100%;
height: 60px;
background-color: #cccccc;
vertical-align: middle;
text-align: center;
font-size:3em;
}
.bottom{
position: fixed;
bottom: 0;
left: 0;
z-index: 999;
display:block;
}
</style>
<div style="height:2000px;"></div>
<div id="footer" style="display:none" > This is your footer</div>
<div style="height:700px"></div>
Try to change the number 700 to set where you want to footer to be shown
Say you want the header to show when you have scrolled 100px from the top.
You can do something like:
$(window).on("scroll", function() {
if(document.body.scrollTop >= 100) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
Say, you want to only show the header if a button with id, callToAction is above the viewport, you can do:
$(window).on("scroll", function() {
if(document.getElementById('callToAction').getBoundingClientRect().top <= 0) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
This code var y = $(this).scrollTop(); get your scroll height from top.
$(window).scroll(function() {
var y = $(this).scrollTop();
if (y > 800) { // scroll gets at a certain height
$('.bottomDiv').fadeIn();
} else {
$('.bottomDiv').fadeOut();
}
});
If I correctly understand your question you need to change documentHeight with value what you want.
Example: documentHeight = 150; not documentHeight = $(document).height();
It is good idea to rename documentHeight variable.
Edit
The thing that was bothering me, was that if you drag the div all the way to the bottom right, then you make the browsers size larger, the div isn't within its parents view, until you actually drag it. Once you drag it, it snaps back within its parents view.
How can I make the div stay in its parent view even after you resize the browser?
JSFiddle
See code snippet bellow.
Older
I have a div which I made draggable through JQuery UI. I want it to be positioned with a percentage value. This way, when you resize the browser, the div will be relatively, or proportionally at the same position.
I checked out this answer, and followed what it said. When I output the left and top position, the numbers were not accurate. When I drag the div all the way to the bottom right, it gives me the following output:
66.55518394648828%
92.71255060728744%
Actually, it does depend on the window size, but the point is, the numbers aren't 100% for left and right.
How can I keep the div at the same position proportionally, when the browser resizes?
Relevant Code:
stop: function () {
console.log(parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
console.log(parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");
}
JSFiddle
Code Snippet
var wrapper = $('#fixed');
var dragDiv = $('#draggable');
dragDiv.css({
'top': ($(window).height() / 2) - (dragDiv.outerHeight() / 2),
'left': ($(window).width() / 2) - (dragDiv.outerWidth() / 2)
});
dragDiv.draggable({
containment: "parent", // <- keep draggable within fixed overlay
stop: function() {
$(this).css("left", parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
$(this).css("top", parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");
console.log(parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
console.log(parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");
}
});
body {
/*width: 2000px;
height: 2000px;*/
background-image: url("http://www.freevector.com/site_media/preview_images/FreeVector-Square-Patterns-Set.jpg");
}
#fixed {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.25)
}
#draggable {
color: lightblue;
background-color: red;
width: 200px;
position: absolute;
}
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div id="fixed">
<div id="draggable">Drag Me!</div>
</div>
The problem is the the parent container to the dragable element has the fixed position.
You can't position items relative to a fixed element.
$(this).css("left") // this refers to $('#draggable')
This is not giving you a left position relative to the fixed container, but rather the body element which has padding on it. So either set the html, body, and #fixed container to have a height and width of 100% and make them position relative.
OR
Remove the padding and margin from your body and html element
body, html{ margin: 0px; padding: 0px;}
Fiddle with body, html, and #fixed at 100%
Fiddle with 0 padding and margin
EDIT
I created a new event to fire every time the window is resized. The event checks to see if the dragable div is outside the bounds of the window. Adjusting as necessary to keep the element in view. I used the code WITHOUT the fixed element because it is not necessary. Let me know if you have any questions.
JS
$(window).resize(function () {
if ($(window).innerWidth() > $(dragDiv).width()) {
var oLeft = parseInt($(window).innerWidth() - $(dragDiv).width());
var posLeft = parseInt($(dragDiv).css("left"));
if (posLeft > oLeft) {
$(dragDiv).css("left", oLeft);
toPercent();
}
}
if ($(window).innerHeight() > $(dragDiv).height()) {
var oTop = parseInt($(window).innerHeight() - $(dragDiv).height());
var posTop = parseInt($(dragDiv).css("top"));
if (posTop > oTop) {
$(dragDiv).css("top", oTop);
toPercent();
}
}
});
function toPercent() {
$(dragDiv).css("left", parseInt($(dragDiv).css("left")) / (wrapper.innerWidth() / 100) + "%");
$(dragDiv).css("top", parseInt($(dragDiv).css("top")) / (wrapper.innerHeight() / 100) + "%");
}
Updated Fiddle for question part 2
My website at the moment has three sections in a single scroll layout. With a Heading for two sections: About & Contact (these are div boxes) that animate when you scroll to the bottom of the page. What I'm trying to achieve is having the animation take place when the user scrolls down and hits the bottom of each (div box) section as opposed to the bottom of the website.
I believe I need to implement the .offset() function but unsure if that is correct?
Any help would be greatly appreciated.
CSS
.header {
display: none;
position: relative;
left: 0px;
right: 0px;
top: 500px;
height: 80px;
width: 100%;
background:red;
color: #fff;
text-align: center;
}
JS
var header = $('.header'),
extra = 10; // In case you want to trigger it a bit sooner than exactly at the bottom.
header.css({ opacity: '0', display: 'block' });
$(window).scroll(function() {
var scrolledLength = ( $(window).height() +extra) + $(window).scrollTop(),
documentHeight = $(document).height();
console.log( 'Scroll length: ' + scrolledLength + ' Document height: ' + documentHeight )
if( scrolledLength >= documentHeight ) {
header
.addClass('top')
.stop().animate({ top: '20', opacity: '1' }, 800);
}
else if ( scrolledLength <= documentHeight && header.hasClass('top') ) {
header
.removeClass('top')
.stop().animate({ top: '500', opacity: '0' }, 800);
}
});
Fiddle - http://jsfiddle.net/SFPpf/480/
Looks like position() would be better in this case. The position method is relative to the document whereas offset is relative to the parent element. It returns an object with the properties "top" and "left". It can only return the position of one element at a time, so for the first div, you would need to use first() and eq() to get a specific one.
The bottom of a .fillWindow will be its vertical position + its height.
var $fillWindow = $(".fillWindow").first(), // or eq() for others
position = $fillWindow.position(),
height = $fillWindow.height();
//bottom = position.top + height;
scrollTop() can now be used to check when the user scrolls past the .fillWindow.
if ( $(window).scrollTop() >= position.top ) {
// do the animation here
} else {
// do something else
}
Edit: I just caught my mistake. It should be $(window).scrollTop(). You should also just test for scrollTop being at the top of the .fillWindow.
I have implemented a parallax scrolling effect based on a tutorial I found. The effect works great. However, when I specify the background images, I am unable to control the y (vertical) axis. This is causing problems because I'm trying to set locations on multiple layered images.
Any thoughts on what's causing the problem?
Here is one external script:
$(document).ready(function(){
$('#nav').localScroll(800);
//.parallax(xPosition, speedFactor, outerHeight) options:
//xPosition - Horizontal position of the element
//inertia - speed to move relative to vertical scroll. Example: 0.1 is one tenth the speed of scrolling, 2 is twice the speed of scrolling
//outerHeight (true/false) - Whether or not jQuery should use it's outerHeight option to determine when a section is in the viewport
$('#mainimagewrapper').parallax("50%", 1.3);
$('#secondaryimagewrapper').parallax("50%", 0.5);
$('.image2').parallax("50%", -0.1);
$('#aboutwrapper').parallax("50%", 1.7);
$('.image4').parallax("50%", 1.5);
})
This is another external script:
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
Here is the CSS for one section:
#aboutwrapper {
background-image: url(../images/polaroid.png);
background-position: 50% 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: white;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
#aboutwrapper .image4 {
background: url(../images/polaroid2.png) 50% 0 no-repeat fixed;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
.image3{
margin: 0 auto;
min-width: 970px;
overflow: auto;
width: 970px;
}
Both of these are being called to achieve the parallax scrolling. I really just want to more specifically control the background image locations. I've tried messing with the CSS background position and I've messed with the first javascript snippet as well. No luck.
just a quick shot, have you tried actually placing the images, either in a div or just using the img src tag to actually move the element rather than manipulating the y axis of a background image?
I found this jsfiddle here at stackoverflow, but the solution provided by the person is very jumpy. http://jsfiddle.net/BramVanroy/ZVzEe/ I need something very smooth.
var secondary = $("#secondary-footer");
secondary.hide().addClass("fixed").fadeIn("fast");
$(window).scroll(function() {
if (secondary.offset().top >= ($(document).height() - 350)) {
secondary.removeClass("fixed");
}
else if(secondary + ":not('.fixed')") {
secondary.addClass("fixed");
}
});
How I need the sticky footer to work is for it to show the footer as a narrow bar at the bottom of the page while still scrolling through the content. Once the bottom of the page is reached with the scrollbar, the footer will expand in height.
The jsfiddle provided is very close to how I need this to work, but I need something very smooth. And another note, the height of the fully expanded footer is not fixed. Thanks to everyone for your help.
demo
jQuery
var secondary = $("#secondary-footer");
secondary.hide().addClass("fixed").fadeIn("fast");
$(window).scroll(function() {
var scrollBottom = $(window).scrollTop() + $(window).height();
$("#content").css("bottom",secondary.height());
var maxHeight = 350; // set maximum height of the footer here
var minHeight = 120; // set the minimum height of the footer here
secondary.height(maxHeight - ($(document).height() - scrollBottom));
if (secondary.height() <= minHeight) secondary.height(minHeight);
});
CSS
#content {
width: 90%;
margin: 0 auto;
padding: 0.5em;
background: #dedede;
position:relative; /* added this */
}
#secondary-footer {
width: 100%;
height: 120px;
background: #666;
position: fixed;
bottom: 0;
left: 0;
}
/* removed #secondary-footer.fixed and merged content with #secondary-footer */
Another solution: http://jsfiddle.net/27rNu/
jQuery
$(document).ready(function() {
var secondary = $("#secondary-footer");
secondary.addClass("fixed");
var windowH = $('#wrapper').outerHeight(true);
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if (scrollVal < (windowH - 350 * 2)) {
secondary.addClass("fixed");
}
else {
secondary.removeClass("fixed");
}
});
});
I also added a "wrapper" div around the whole html.