table needs to be fixed during scrolling - javascript

I have 3 tables and one of them I want to be fix after scroll more then specific distance
var distance = $("#thead").offset().top;
$(window).scroll(function () {
var wdistance = $(window).scrollTop();
if (wdistance > distance) {
};
})
demo jsfiddle
I want to say when this "if" is correct then position of div with "thead" id become fixed on top of the other tables when scrolling the page. and after the div with id "first" is finish then <div id="thead"></div> come back to previous place.

You can create a .fixed class and add/remove that to/from the #thead element, as follows:
CSS
* { padding: 0; margin: 0; } /* Tiny reset for removing paddings and margins */
.fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
Note that, you have to remove the padding/margin from the <body> element to adjust the width of each column (when the #thead is positioned).
Or use the same padding/margin for the positioned #thead element as well.
var $table = $("#thead"),
$window = $(window),
distance = $table.offset().top;
$window.scroll(function () {
var wdistance = $window.scrollTop();
if (wdistance > distance) {
$table.addClass('fixed');
} else {
$table.removeClass('fixed');
}
});
WORKING DEMO.

Related

Animate div detect top or bottom of it

I want my div to animate when that div is almost half while scrolling.
How can I do it? It's not on a fixed div but its like sticky sidebar
Just like on this website sample
this is my code
$(function(){ // document ready
if ($('.filter-container').length) { // make sure ".filter-container" element exists
var el = $('.filter-container');
var stickyTop = $('.filter-container').offset().top; // returns number
var stickyHeight = $('.filter-container').height();
$(window).scroll(function(){ // scroll event
var limit = $('#footer').offset().top - stickyHeight - 100;
var windowTop = $(window).scrollTop(); // returns number
if (stickyTop < windowTop){
el.css({ position: 'fixed', top: 0, width: 280 });
}
else {
el.css({ position: 'static', width: 280 });
}
if (limit < windowTop) {
var diff = limit - windowTop;
el.css({top: diff});
}
});
}
});
You could write a jQuery function using Waypoints.
Or more easily (in my opinion) but with higher payload cost use Bootstrap affix. In this case you keep your current css but then add some Bootstrap properties to the div, in your case:
<div class="filter-container" data-spy="affix" data-offset-top="60" data-offset-bottom="200">
This will add the classes .affix-top to the div UNTIL the user scrolls past 60px. Then if will change to .affix when the user gets 200px from the bottom it will change to .affix-bottom to the class.
This jsfiddle shows it quite well:
http://jsfiddle.net/skelly/df8tb/
This shows the appropriate css to get the sticky effect.

A cleaner way for a fixed div at bottom of the window but stays above the footer and triggers on page width

I've created a sticky bar to stay at the bottom of the window. As the user scrolls down to the bottom of the page the same bar will stay fixed until the footer shows, then removes its fixed position, temporarily, to stay above the footer until the user scrolls back up and it remains fixed again.
I only want to happen when the page is wider than 680px. Anything under that will keep the sticky bar in a default position (CSS: position:inherit).
This is the website: http://ttd.firefly-digital.co.uk
It works as expected. However, when I test on Chrome in Mac it triggers my CPU fan which suggests this not very efficient and with my limited JavaScript skills, wondered if there is a cleaner way to achieve this is?
This is the current js code:
$(window).scroll(function(event) {
var scroll = $(this).scrollTop();
var docHeight = $(document).height();
var windowHeight = $(window).height();
var footerHeight = $('.footer').height();
if(docHeight - (windowHeight + scroll) < footerHeight) {
$('.contact-bar').css({
bottom: footerHeight - (docHeight - (windowHeight + scroll))
});
} else {
$('.contact-bar').css({
bottom: 0
});
}
});
var windowWidth = $(window).width();
$(window).resize(function() {
windowWidth = $(window).width();
if(windowWidth > 680) {
$('.contact-bar').css({
position: "fixed"
});
} else {
$('.contact-bar').css({
position: "inherit"
});
}
});
CSS code
.contact-bar {
background: $contact-bar;
width: 100%;
height: 40px;
text-align: center;
position: fixed;
bottom: 0;
z-index: 10;
}
You can do it in reverse. Make it so that the bar, without position fixed, is above the footer without any JavaScript (incl. media queries). Than add a fixed class with position:fixed and bottom:0 that will be added accordingly. Like so:
.contact-bar.fixed { position:fixed; bottom:0; }
The jquery code that will trigger this, is as follows:
$(window).scroll(function (event) {
var windowTop = $(this).scrollTop();
if (windowTop >= $(".footer").offset().top) {
$(".contact-bar").addClass("fixed");
} else {
$(".contact-bar").removeClass("fixed");
}
});
Then add a few lines that the above code will only fire if the window width is > 680, either with jquery or pure javascript. For example with:
if ($(window).width() < 960) { // above function }
Do note I have not tested this, so please comment if it doesn't work. Credit: Preventing element from displaying on top of footer when using position:fixed
You better use classes to target your elements, at least to prevent jQuery from traversing the whole DOM using selectors appropriately which is good in performance.

My sticky header causes the subsequent div to jump about 100 pixels when the navbar reaches the top of the page, can't figure out a fix?

As my title says, my sticky header is causing the subsequent div to jump about 100 pixels when the navbar reaches the top of the page. It's like the home div is magically losing 100 pixels of its height. I've tried a couple things but haven't been able to get this to work.
I have added plugins for smooth scrolling but couldn't get it to work in the jsfiddle. If you scroll down slowly when the navbar is getting to the top of the page, you will notice the skip.
Thanks for your help!
http://jsfiddle.net/g9N78/2/
here is the code I'm using for the sticky header:
<script>
function moveScroller() {
var move = function() {
var st = $(window).scrollTop();
var ot = $("#nav").offset().top;
var s = $(".nav");
if(st > ot) {
s.css({
position: "fixed",
top: "0",
background: "rgba(0,0,0,0.65)"
});
} else {
if(st <= ot) {
s.css({
position: "",
top: "",
background: "black"
});
}
}
};
$(window).scroll(move);
move();
}
</script>
<script type="text/javascript">
$(function() {
moveScroller();
});
</script>
Since you are removing that object from the DOM flow the space is available and the element under takes it, you can just add some margin to #home like this:
$('#home').css('marginTop','100px');
Check this Demo http://jsfiddle.net/g9N78/3/
Use the jQuery .height() method to find out the height of your nav bar, save it to a variable, then apply that height to the top margin of the page, to make it fill the space that the nav bar used to occupy.
$(".nav").height();
$('#home').css('marginTop', navHeight);
See the fiddle below...
http://jsfiddle.net/g9N78/8/
jQuery:
function moveScroller() {
var move = function() {
var st = $(window).scrollTop();
var ot = $("#nav").offset().top;
var s = $(".nav"),
navHeight = s.height();
if(st > ot) {
s.css({
position: "fixed",
top: "0",
background: "rgba(0,0,0,0.65)"
});
$('#home').css('marginTop', navHeight);
} else {
if(st <= ot) {
s.css({
position: "",
top: "",
background: "black"
});
}
$('#home').css('marginTop', '0');
}
};
$(window).scroll(move);
move();
}
There is no magic involved. As long as you do not reach the scroll-top, the header is position:static. The following div will be displayed under the Top. As soon as the element is set to position: fixed, you "lose" the height of the header, causig the optical jump.
I don't think you need Javascript for your header to be sticky.
Try removing the javascript and add this css:
body
{
padding-top: 90px;
}
.nav
{
position: fixed;
top: 0px;
height: 90px;
width: 100%;
}
Edit: Sorry I did not think about your Logo. So this will not work for you like that.

Sticky Header / Javascript

Good morning I am working on a sticky header for my site, I've got it working but it seems to snap into place, I want to be smooth! how do I go about this?
My site: http://www.trevorpeters.co.uk/tpwebdesign
CSS:
.sticky {
position: fixed;
width: 100%;
left: 0;
top: 0;
z-index: 100;
border-top: 0;
}
JS
$(document).ready(function() {
var stickyNavTop = $('.nav').offset().top;
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
By default the header is in your document flow, 'pushing' the rest of the content down. If you make it sticky, it doesn't push the rest of the document down making it snap upwards. You can fix this by making your banner sticky from the start and giving your content a top margin equal to the height of your header. This way you can just get rid of the javascript all together.

Scrollpane on the bottom, css is hacky, javascript is hard

I want to put a bar on the bottom of my page containing a varying number of pictures, which (if wider than the page) can be scrolled left and right.
The page width is varying, and I want the pane to be 100% in width.
I was trying to do a trick by letting the middle div overflow and animate it's position with jquery.animate().
Like this:
Here is a fiddle without the js: http://jsfiddle.net/SoonDead/DdPtv/7/
The problems are:
without declaring a large width to the items holder it will not overflow horizontally but vertically. Is this a good hack? (see the width: 9000px in the fiddle)
I only want to scroll the middle pane if it makes sense. For this I need to calculate the width of the overflowing items box (which should be the sum of the items' width inside), and the container of it with the overflow: hidden attribute. (this should be the width of the browser window minus the left and right buttons).
Is there a way to calculate the length of something in js without counting all of it's childrens length manually and sum it up?
Is there a way to get the width of the browser window? Is there a way to get a callback when the window is resized? I need to correct the panes position if the window suddenly widens (and the items are in a position that should not be allowed)
Since the window's width can vary I need to calculate on the fly if I can scroll left or right.
Can you help me with the javascript?
UPDATE: I have a followup question for this one: Scroll a div vertically to a desired position using jQuery Please help me solve that one too.
Use white-space:nowrap on the item container and display:inline or display:inline-block to prevent the items from wrapping and to not need to calculate or set an explicit width.
Edit:: Here's a live working demo: http://jsfiddle.net/vhvzq/2/
HTML
<div class="hscroll">
<ol>
<li>...</li>
<li>...</li>
</ol>
<button class="left"><</button>
<button class="right">></button>
</div>
CSS
.hscroll { white-space:nowrap; position:relative }
.hscroll ol { overflow:hidden; margin:0; padding:0 }
.hscroll li { list-style-type:none; display:inline-block; vertical-align:middle }
.hscroll button { position:absolute; height:100%; top:0; width:2em }
.hscroll .left { left:0 }
.hscroll .right { right:0 }
JavaScript (using jQuery)
$('.hscroll').each(function(){
var $this = $(this);
var scroller = $this.find('ol')[0];
var timer,offset=15;
function scrollLeft(){ scroller.scrollLeft -= offset; }
function scrollRight(){ scroller.scrollLeft += offset; }
function clearTimer(){ clearInterval(timer); }
$this.find('.left').click(scrollLeft).mousedown(function(){
timer = setInterval(scrollLeft,20);
}).mouseup(clearTimer);
$this.find('.right').click(scrollRight).mousedown(function(){
timer = setInterval(scrollRight,20);
}).mouseup(clearTimer);
});
Thanks Phrogz for this part -- give the image container the white-space: nowrap; and display: inline-block;.
You can calculate the width without having to calculate the width of the children every time but you will need to calculate the width of the children once.
//global variables
var currentWidth = 0;
var slideDistance = 0;
var totalSize = 0;
var dispWidth = (winWidth / 2); //this should get you the middle of the page -- see below
var spacing = 6; //padding or margins around the image element
$(Document).Ready(function() {
$("#Gallery li").each(function () {
totalSize = totalSize + parseFloat($(this).children().attr("width"));// my images are wrapped in a list so I parse each li and get it's child
});
totalSpacing = (($("#Gallery li").siblings().length - 1) * spacing); //handles the margins between pictures
currentWidth = (parseFloat($("#Gallery li.pictureSelected").children().attr("width")) + spacing);
maxLeftScroll = (dispWidth - (totalSize + totalSpacing)); //determines how far left you can scroll
});
function NextImage() {
currentWidth = currentWidth + (parseFloat($("#Gallery li.pictureSelected").next().children().attr("width")) + spacing); //gets the current width plus the width of the next image plus spacing.
slideDistance = (dispWidth - currentWidth)
$("#Gallery").animate({ left: slideDistance }, 700);
}
There is a way to get the browser window with in javascript (jQuery example).
and there is a way to catch the resize event.
var winWidth = $(window).width()
if (winWidth == null) {
winWidth = 50;
}
$(window).resize(function () {
var winNewWidth = $(window).width();
if (winWidth != winNewWidth) {
window.clearTimeout(timerID);
timerID = window.setInterval(function () { resizeWindow(false); }, 100);
}
winWidth = winNewWidth;
});
On my gallery there's actually quite a bit more but this should get you pointed in the right direction.
You need to change your #items from
#items
{
float: left;
background: yellow;
width: 9000px;
}
to
#items {
background: yellow;
}
Then calculate the width very easily with jQuery
// #items width is calculated as the number of child .item elements multiplied by their outerWidth (width+padding+border)
$("#items").width(
$(".item").length * $(".item").outerWidth()
);
and simply declare click events for the #left and #right elements
$("#left").click(function() {
$("#middle").animate({
scrollLeft: "-=50px"
}, 'fast');
});
$("#right").click(function() {
$("#middle").animate({
scrollLeft: "+=50px"
}, 'fast');
});
jsFiddle link here
EDIT
I overlooked that detail about the varying image widths. Here is the correct way to calculate the total width
var totalWidth = 0;
$(".item").each(function(index, value) {
totalWidth += $(value).outerWidth();
});
$("#items").width(totalWidth);

Categories

Resources