There are 3 divs,
1. Top bar
2. slider
3. navigation
I implemented parallax scroll on navigation with the code below.
<script>
$.fn.moveIt = function(){
var $window = $(window);
var instances = [];
$(this).each(function(){
instances.push(new moveItItem($(this)));
});
window.onscroll = function(){
var scrollTop = $window.scrollTop();
instances.forEach(function(inst){
inst.update(scrollTop);
});
}
}
var moveItItem = function(el){
this.el = $(el);
this.speed = parseInt(this.el.attr('data-scroll-speed'));
};
moveItItem.prototype.update = function(scrollTop){
var pos = scrollTop / this.speed;
this.el.css('transform', 'translateY(' + -pos + 'px)');
};
$(function(){
$('[data-scroll-speed]').moveIt();
});
</script>
The script is working perfectly, but i want the bottom navigation when scrolled to the top sticks at 30pixels from top, so i implemented the css below.
nav{
position: -webkit-sticky;
position: sticky;
top: 30px;
}
both code dosent work together, it may be a position issue, I want to get both this working together, any suggestion please.
Related
box2 is a fix positioned element, I need it stops at the top and bottom of box1 when scrolling. Any help would be appreciated.
$(window).scroll(function() {
var h1 = $('.box1').height();
var h2 = $('.box2').height();
var h3 = $('.footer').outerHeight(true);
$('.box2').css('bottom', h3);
});
example
If I understand the question correctly, you want box2 to appear static within the viewport, except it should never go above or below box1's extent.
Use this code:
$(window).scroll(function() {
var scrollTop= $(window).scrollTop(),
b1= $('.box1'),
b2= $('.box2'),
min= b1.position().top,
max= (b1.position().top + b1.outerHeight()) - b2.outerHeight();
b2.css({
top: Math.min(Math.max(scrollTop,min),max) - scrollTop
});
});
Working Fiddle
Great answer from Rick Hitchcock, made some improvements:
var $b1 = $('.box1'); // 1
var $b2 = $('.box2'); // 1
var min = $b2.position().top; // 2
$(window).scroll(function() {
var scrollTop = $(window).scrollTop();
var max = ($b1.position().top + $b1.outerHeight()) - $b2.outerHeight();
$b2.css({
top: Math.min(Math.max(scrollTop, min), max)
});
});
Cache DOM queries
Make min the original top of $b2 on page load.
jsbin demo
Good morning!
I want to share with you a simple script I made for the purposes of my company new website. It allows you to make a floating navigation bar which smoothly changes its background.
For now it's working with jQuery. My question is - is it possible to made this in pure CSS? My previous idea was to make navigation container with overflow: hidden and position: absolute + menu with position: fixed. Everything worked well until I realized that Firefox can't handle with this combination.
I'm waiting for yours ideas :)
Here's the code and preview:
var nav = $('.nav'),
navHeight = nav.height();
// Duplicate navigation
var navReversed = nav
.clone(true)
.addClass('nav-reversed')
.insertAfter(nav);
var navs = $('.nav'),
slides = $('.slide');
/* ... */
// onScroll event
$(window).on('scroll resize', function() {
var scrollTop = $(document).scrollTop(),
slide;
// Find first visible slide
slides.each(function() {
if ($(this).offset().top > scrollTop)
return false;
slide = $(this);
});
if (slide.length) {
var id = '#' + slide.attr('id'),
slideNext = slide.next('.slide');
var clipTop = clipBottom = 'auto';
if (slide.hasClass('slide-reversed')) {
clipBottom = Math.max(slideNext.offset().top - scrollTop, 0);
}
else {
clipTop = navHeight;
if (slideNext.length && slideNext.hasClass('slide-reversed')) {
clipTop = Math.min(slideNext.offset().top - scrollTop, clipTop);
}
}
if (clipTop !== 'auto') {
clipTop = Math.round(clipTop) + 'px';
}
if (clipBottom !== 'auto') {
clipBottom = Math.round(clipBottom) + 'px';
}
navReversed.css('clip', 'rect('+clipTop+',auto,'+clipBottom+',auto)');
/* ... */
}
}).trigger('scroll');
Full version: http://jsfiddle.net/greenek/NL7Fh/
You can try checkbox hack http://css-tricks.com/the-checkbox-hack/, there are :target too but you can't higlight the link. http://codepen.io/anon/pen/lqvpA
jsfiddle: http://jsfiddle.net/R3G2K/1/
I have multiple divs with content, and each one has a header. I'd like to make the last header that left the viewport to be "sticky" or fixed to the top of the viewport.
I've seen a few different approaches to this, but none of them seem to work for multiple headers.
$('.content').scroll(function(){
console.log('scrolling')
$('.itemheader').each(function(){
var top = $(this).offset().top;
console.log(top);
if(top<25){
$(this).addClass('stick');
}else{
$(this).removeClass('stick');
}
})
});
I think there might be a conflict since each header has the same class name, and no unique identifier, so my above attempt isn't working out right.
http://jqueryfordesigners.com/iphone-like-sliding-headers/
This was exactly what I was looking for:
http://jqueryfordesigners.com/demo/header-slide.html
$(document).ready(function () {
// 1. grab a bunch of variables
var $container = $('#box');
var $headers = $container.find('h2');
var zIndex = 2;
var containerTop = $container.offset().top + parseInt($container.css('marginTop')) + parseInt($container.css('borderTopWidth'));
var $fakeHeader = $headers.filter(':first').clone();
// 2. absolute position on the h2, and fix the z-index so they increase
$headers.each(function () {
// set position absolute, etc
var $header = $(this), height = $header.outerHeight(), width = $header.outerWidth();
zIndex += 2;
$header.css({
position: 'absolute',
width: $header.width(),
zIndex: zIndex
});
// create the white space
var $spacer = $header.after('<div />').next();
$spacer.css({
height: height,
width: width
});
});
// 3. bind a scroll event and change the text of the take heading
$container.scroll(function () {
$headers.each(function () {
var $header = $(this);
var top = $header.offset().top;
if (top < containerTop) {
$fakeHeader.text($header.text());
$fakeHeader.css('zIndex', parseInt($header.css('zIndex'))+1);
}
});
});
// 4. initialisation
$container.wrap('<div class="box" />');
$fakeHeader.css({ zIndex: 1, position: 'absolute', width: $headers.filter(':first').width() });
$container.before($fakeHeader.text($headers.filter(':first').text()));
});
I am building my sister a website at SarahNWatson.com/new. I have it set up as a big photo/video album. For actual content pages, such as her Bio, I have it so that it opens a modal window.
Right now I have the modal window so that the height starts at 0px and then animates open, however this gives me a slide down effect. I want it to open outwards as if something were in the box pushing in both directions. How can I accomplish this?
Here's the code:
function createModal(filler) {
var $this = $(this);
var $body = $('body');
var winHeight = $(window).height();
var winWidth = $(window).width();
$body.prepend('<div id="blackout">');
$("#blackout").css({ height:winHeight }).fadeIn(1800);
$body.prepend('<div id="modal_window">');
$("#modal_window").html(filler).fadeIn(2000);
var modalHeight = $("#modal_window").height();
var modalWidth = $("#modal_window").width();
var offsetH = winHeight/2 - modalHeight;
var offsetW = winWidth/2 - modalWidth/2;
$("#modal_window").css({ top:offsetH, left:offsetW, height:'0px' }).animate({ height:modalHeight });
}
And the CSS:
#modal_window {
position: absolute;
z-index: 1000;
width: 600px;
background: rgba(0,0,0,.8);
padding: 15px;
}
Start with offsetH = winHeight/2 and offsetW = winWidth/2. Then, animate all of the top, left, and height CSS properties. The final top will be (winHeight - modalHeight)/2 and final left will be (winWidth - modalWidth)/2.
function createModal(filler) {
var $this = $(this);
var $body = $('body');
var winHeight = $(window).height();
var winWidth = $(window).width();
$body.prepend('<div id="blackout">');
$("#blackout").css({ height:winHeight }).fadeIn(1800);
$body.prepend('<div id="modal_window">');
$("#modal_window").html(filler).fadeIn(2000);
var modalHeight = $("#modal_window").height();
var modalWidth = $("#modal_window").width();
var offsetH1 = winHeight/2;
var offsetH2 = (winHeight-modalHeight)/2;
var offsetW = (winWidth-modalWidth)/2;
$("#modal_window")
.css({ top:offsetH1, left:offsetW, height:'0px' })
.animate({ top:offsetH2, height:modalHeight });
}
UPDATE: Code sample updated to only animate vertically.
Essentially, you're moving the box up as it grows taller. So instead of sliding down it gives the appearance of expanding from the middle.
You could give it a margin-top of half the ultimate height (modalHeight) and add marginTop:"toggle" to your animation:
.animate({ height:modalHeight, marginTop:"toggle"})
Try using the CSS setting Bottom instead of Top. You should then use the bottom of the element to position it thus having it animte upwards instead of downwards.
.animate() always animate away from the anchor.
I would like to create a div, that is situated beneath a block of content but that once the page has been scrolled enough to contact its top boundary, becomes fixed in place and scrolls with the page. I know I've seen at least one example of this online but I cannot remember it for the life of me.
Any thoughts?
[Working demo]
var el = $("#sticky");
var win = $(window);
var width = el.width();
var height = el.height();
var win_height = $(window).height();
window.onscroll = function() {
var offset = el.offset().top + height - win_height;
if ( win.scrollTop() > offset ) {
window.onscroll = function() {
el.css({
width: width,
position: "absolute",
top: win.scrollTop() + win_height - height
});
};
}
};
If you don't need to support IE based browsers you can use:
position: "fixed"
bottom: 0